web-dev-qa-db-fra.com

CTE multiple dans une requête unique

Est-il possible de combiner plusieurs CTE dans une requête unique avec arel? Je cherche un moyen d'obtenir un résultat comme celui-ci:

WITH 'cte1' AS (
...
),
WITH RECURSIVE 'cte2' AS (
...
),
WITH 'cte3' AS (
...
)
SELECT ... FROM 'cte3' WHERE ...

Comme vous pouvez le constater, j'ai un CTE récursif et deux non récursifs.

37
axvm

Utilisez la clé Word WITH une fois en haut. Si l'une de vos expressions de table commune (CTE) est récursive (rCTE), vous devez ajouter le mot clé RECURSIVE en haut une fois également, même si tous les CTE ne sont pas récursifs:

WITH RECURSIVE
  cte1 AS (...)         -- can still be non-recursive
, cte2 AS (SELECT ...
           UNION ALL
           SELECT ...)  -- recursive term
, cte3 AS (...)
SELECT ... FROM cte3 WHERE ...

Le manuel:

Si RECURSIVE est spécifié, il autorise une sous-requête SELECT à se référencer par son nom.

Gras accent mien. Et encore plus perspicace:

Un autre effet de RECURSIVE est que les requêtes WITH ne doivent pas nécessairement être commandées : une requête peut en référencer une plus récente. dans la liste. (Cependant, les références circulaires ou la récursion mutuelle ne sont pas implémentées.) Sans les requêtes RECURSIVE, WITH ne peuvent référencer que les requêtes frères WITH qui étaient antérieures dans la WITH liste.

Gras accent mien à nouveau. Cela signifie que l'ordre des clauses WITH est sans signification lorsque la clé RECURSIVE mot a été utilisée.

BTW, depuis cte1 et cte2 dans l'exemple ne sont pas référencés dans les commandes SELECT extérieures et sont des commandes simples SELECT elles-mêmes (pas d'effets collatéraux), elles ne sont jamais exécutées (à moins d'être référencées dans cte3).

63
Erwin Brandstetter

Oui. Vous ne répétez pas le WITH. Vous utilisez juste une virgule:

WITH cte1 AS (
...
),
     cte2 AS (
...
),
     cte3 AS (
...
)
SELECT ... FROM 'cte3' WHERE ...

Et: Utilisez uniquement des guillemets simples pour les constantes chaîne et date. Ne les utilisez pas pour les alias de colonnes. De toute façon, ils ne sont pas autorisés pour les noms CTE.

19
Gordon Linoff