1 つの PostgreSQL クエリで複数の WITH ステートメントを使用するにはどうすればよいでしょうか? 質問する

1 つの PostgreSQL クエリで複数の WITH ステートメントを使用するにはどうすればよいでしょうか? 質問する

私は、WITH ステートメントを使用して、実質的に複数の TEMP テーブルを「宣言」したいと思います。実行しようとしているクエリは次のようになります。

WITH table_1 AS (
SELECT GENERATE_SERIES('2012-06-29', '2012-07-03', '1 day'::INTERVAL) AS date
)

WITH table_2 AS (
SELECT GENERATE_SERIES('2012-06-30', '2012-07-13', '1 day'::INTERVAL) AS date
)

SELECT * FROM table_1
WHERE date IN table_2

もう読んだPostgreSQL ドキュメント複数のステートメントを使用して調査しましたがWITH、答えを見つけることができませんでした。

ベストアンサー1

他のコメントによると、2番目の共通テーブル式[CTE]の前にはWITHステートメントではなくカンマが置かれています。

WITH cte1 AS (SELECT...)
, cte2 AS (SELECT...)
SELECT *
FROM
    cte1 c1
    INNER JOIN cte2 c2
    ON ........

実際のクエリに関しては、この構文は PostgreSql、Oracle、および sql-server で機能するはずです。後者では通常、WITHセミコロン ( ;WTIH) を使用しますが、これは通常、sql-server のユーザー (私を含む) が、CTE が定義される前に終了する必要がある前のステートメントを終了しないためです...

ただし、ステートメントに関して 2 番目の構文の問題があることに注意してくださいWHERE。は、実際には table_2 から値/列を参照していないため、有効ではありません。またはのWHERE date IN table_2方が好みなので、で機能する構文は次のとおりです。INNER JOININExistsJOIN

WITH table_1 AS (
SELECT GENERATE_SERIES('2012-06-29', '2012-07-03', '1 day'::INTERVAL) AS date
)

, table_2 AS (
SELECT GENERATE_SERIES('2012-06-30', '2012-07-13', '1 day'::INTERVAL) AS date
)

SELECT * 
FROM
     table_1 t1
     INNER JOIN 
     table_2 t2
     ON t1.date = t2.date
;

以前の状態を維持したい場合、通常は IN よりも EXISTS の方が適していますが、IN を使用するには、where に実際の SELECT ステートメントが必要です。

SELECT * 
FROM
     table_1 t1
WHERE t1.date IN (SELECT date FROM table_2);

IN は、date潜在的に になる可能性がある場合に非常に問題となるNULLため、 を使用したくない場合は、JOINをお勧めしますEXISTS。次のようになります。

SELECT * 
FROM
     table_1 t1
WHERE EXISTS (SELECT * FROM table_2 t2 WHERE t2.date = t1.date);

おすすめ記事