CTE Multiple dans une seule requête
est-il possible de combiner plusieurs CTEs en une seule requête avec arel
? Je cherche le moyen d'obtenir le résultat comme ceci:
WITH 'cte1' AS (
...
),
WITH RECURSIVE 'cte2' AS (
...
),
WITH 'cte3' AS (
...
)
SELECT ... FROM 'cte3' WHERE ...
comme vous pouvez le voir, j'ai un CTE récursif et deux non récursifs.
2 réponses
utilisez le mot clé WITH
une fois en haut et si l'une de vos Expressions de la Table commune (CTE) est récursive (rCTE) vous devez ajouter le mot clé RECURSIVE
en haut aussi, même si toutes les expressions de la Table commune (CTE) ne sont pas récursives:
WITH RECURSIVE
cte1 AS (...) -- can still be non-recursive
, cte2 AS (SELECT ...
UNION ALL
SELECT ...) -- recursive term
, cte3 AS (...)
SELECT ... FROM cte3 WHERE ...
si
RECURSIVE
est spécifié, il permet aSELECT
sous - référence elle-même par son nom.
le Gras c'est moi qui souligne. Et, encore plus perspicace:
un autre effet de
RECURSIVE
est queWITH
les requêtes ne doivent pas être commandées : une requête peut renvoyer à une autre qui est plus tard dans la liste. (Cependant, les renvois circulaires, ou récursions mutuelles, ne sont pas mis en œuvre.) SansRECURSIVE
, les requêtesWITH
ne peuvent faire référence qu'à un frère ou une sœur.WITH
les requêtes qui sont plus tôt dans la listeWITH
.
c'est encore moi qui souligne. Ce qui signifie que l'ordre des clauses WITH
est sans signification lorsque le mot clé RECURSIVE
a été utilisé.
BTW, puisque cte1
et cte2
ne sont pas référencés dans l'extérieur SELECT
et sont des commandes simples SELECT
eux-mêmes (pas d'effets collatéraux), ils ne sont jamais exécutés (sauf indication contraire dans cte3
).
Oui. Vous ne répétez pas le WITH
. Vous n'utilisez qu'une virgule:
WITH cte1 AS (
...
),
cte2 AS (
...
),
cte3 AS (
...
)
SELECT ... FROM 'cte3' WHERE ...
et: n'utilisez que des guillemets simples pour les constantes de chaîne et de date. Ne les utilisez pas pour les alias de colonne. Ils ne sont pas autorisés pour les noms CTE de toute façon.