web-dev-qa-db-ja.com

単一クエリでの複数のCTE

単一クエリで複数のCTEをarelと組み合わせることは可能ですか?私はこのような結果を得る方法を探しています:

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

ご覧のように、1つの再帰CTEと2つの非再帰があります。

37
axvm

上部のキーワードWITHonceを使用します。共通テーブル式(CTE)のいずれかが再帰的(rCTE)である場合、すべてのCTEが再帰的でなくても、キーワードRECURSIVEを先頭onceに追加する必要があります。

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

マニュアル:

RECURSIVEが指定されている場合、は[SELECTサブクエリが名前で自身を参照することを許可します。

大胆な強調鉱山。そして、さらに洞察に富んだ:

RECURSIVEのもう1つの効果は、WITHクエリを順序付ける必要がないことです:クエリはリスト内の別のクエリを参照できます。 (ただし、循環参照、または相互再帰は実装されていません。)RECURSIVEがない場合、WITHクエリは、WITHリストの前にある兄弟WITHクエリのみを参照できます。

大胆な強調鉱山。 WITH句の順序は、RECURSIVEキーワードが使用されている場合、meaninglessであることを意味します。

ところで、例のcte1cte2は外側のSELECTで参照されておらず、プレーンなSELECTコマンド自体であるため(副次的な効果はありません)、実行されません(ただし、 cte3)で参照されます。

63

はい。 WITHを繰り返さないでください。コンマを使用するだけです:

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

および:文字列定数と日付定数には単一引用符のみを使用します。列のエイリアスには使用しないでください。とにかくCTE名には使用できません。

19
Gordon Linoff