Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

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

Цитата руководства:

Если указано RECURSIVE, он разрешает a SELECT подзапрос ссылайтесь по имени.

Смелый акцент мой. И еще более проницательным:

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

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

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

Ответ 2

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

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

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