2016-02-07 45 views
14

是否可以將單個查詢中的多個CTE與arel結合?我正在尋找方式來獲得結果是這樣的:單個查詢中的多個CTE

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

正如你所看到的,我有一個遞歸CTE和兩個非遞歸的。

+0

CTE的名稱是_identifier_。標識符不能用單引號括起'WITH'cte1''是無效的(例如'from foobar as'bla'') –

回答

25

使用關鍵字WITH一次在頂部,如果你的任何公用表表達式(CTE)是遞歸(rCTE),你必須在頂部還添加關鍵字RECURSIVE,即使不是所有的熱膨脹係數是遞歸的:

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

Quoting the manual:

如果指定RECURSIVE,它所有ows a SELECT子查詢到 參考名稱。

大膽重視我的。而且,更精闢:

RECURSIVE另一個影響是WITH查詢不需要排序: 查詢可以參考另外一個,就是後來在列表中。 (但是, 循環引用或相互遞歸未實現。) 沒有RECURSIVE,WITH查詢只能引用WITH 查詢,該查詢在WITH列表中較早。

再次強調我的意思。意思是WITH條款的順序是無意義RECURSIVE關鍵字已被使用。

順便說一句,因爲cte1cte2不在外SELECT引用和是純SELECT命令本身(沒有附帶影響),它們從未執行(除非在cte3引用)。

9

是的。你不要重複WITH。您只需使用逗號:

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

並且:只對字符串和日期常量使用單引號。不要將它們用於列別名。無論如何,它們都不允許使用CTE名稱。

+1

但是如果我需要一個具有2個非遞歸的遞歸CTE? – axvm