2016-02-07 10 views
14

単一クエリ内で複数のCTEを組み合わせることは可能ですかarel単一クエリ内の複数のCTE

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

あなたが見ることができるように、私は1つの再帰CTEと二つの非再帰を持っている:私はこのような結果を取得する方法を探しています。

+0

CTEの名前は_identifier_です。識別子は一重引用符で囲まれてはいけません。 'WITH' cte1''は無効です(例えば 'foobar as 'bla'')。 –

答えて

25

使用キーワードWITH一度上部にとあなたの共通テーブル式(CTE)のいずれかを使用すると、また上部にキーワードRECURSIVEを追加する必要があります(RCTE)再帰的である場合でも、すべてではないのCTE場合再帰的である:

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クエリがを注文する必要はないということです: クエリは、後に、リスト内で別のものを参照することができます。ただし、 循環参照または相互再帰は実装されていません。

もう一度大胆に強調します。 キーワードを使用した場合、WITH句の順番がであり、意味がありません。であることを意味します。

ところで、cte1cte2ので、外SELECTで参照し、SELECT平野ですされていませんが、自分自身(無担保効果を)コマンド(cte3で参照しない限り)、それらが実行されることはありません。

9

はい。 WITHを繰り返さないでください。

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

And:文字列と日付の定数にはシングルクォートだけを使用します。列エイリアスには使用しないでください。彼らはとにかくCTEの名前に許可されていません。

+1

2つの非再帰的なCTEが必要な場合は? – axvm

関連する問題