Несколько CTE в одном запросе

можно ли объединить несколько CTEs в одном запросе с arel? Я ищу способ получить такой результат:

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

Как вы можете видеть, у меня есть один рекурсивный CTE и два нерекурсивных.

2 ответов


используйте ключевое слово WITH после вверху, и если любое из ваших общих табличных выражений (CTE) рекурсивно (rCTE), вы должны добавить ключевое слово RECURSIVE вверху также, Даже если не все CTEs рекурсивны:

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

цитирую инструкцию:

если , это позволяет a SELECT подзапрос ссылаться на себя по имени.

жирным выделено мной. И даже более проницательно:

еще один эффект RECURSIVE это WITH запросы не нужно заказывать: запрос может ссылаться на другой, который находится в конце списка. (Однако, циклические ссылки или взаимная рекурсия не реализуются.) Без RECURSIVE, WITH запросы могут ссылаться только на одноуровневых WITH запросы, которые находятся ранее в WITH список.

полужирный курсив опять мой. Это означает, что порядок WITH п. is бессмысленно когда RECURSIVE ключевое слово было использовано.

кстати, так как cte1 и cte2 не указаны во внешнем SELECT и равнины SELECT сами команды (без побочных эффектов), они никогда не выполняются (если не указано в cte3).


да. Вы не повторяете WITH. Вы просто используете запятую:

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

и: используйте только одинарные кавычки для констант строки и даты. Не используйте их для псевдонимов столбцов. Они не допускаются для имен CTE в любом случае.