Db2 (LUW und z) haben interessante Einschränkungen bei rekursiven With
-Klauseln (siehe: Dokumentation). Die Fehlermeldung in ihrer ganzen Pracht:
The fullselect of the recursive common table expression name must be the UNION of two or more fullselects and cannot include column functions, GROUP BY clause, HAVING clause, ORDER BY clause, or an explicit join including an ON clause.
Eine davon ist, dass die On
-Klausel bei Joins im rekursiven Zweig nicht verwendet werden kann. Das ist jedoch bei der Arbeit mit Hierarchien sehr oft notwendig.
WITH prev (id, parent) AS (
SELECT t.id, t.parent
FROM hierarchy t
WHERE t.id = ?
UNION ALL
SELECT t.id, t.parent
FROM hierarchy t
JOIN prev ON t.parent = prev.id
)
Im Falle eines Inner-Joins kann man diese Limitierung einfach umgehen, indem man auf einen Cross-Join mit der Komma-Syntax (,
) ausweicht und die On
-Bedingungen in den Where
-Klausel verschiebt.
WITH prev (id, parent) AS (
SELECT t.id, t.parent
FROM hierarchy t
WHERE t.id = ?
UNION ALL
SELECT t.id, t.parent
FROM hierarchy t
, prev
WHERE t.parent = prev.id
)
In diesem trivialen Beispiel wurde das Schlüsselwort Join
durch ein Komma (,
) ersetzt und On
durch Where
.