我想使用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 documentation并研究过使用多个WITH
语句,但无法找到答案。
答案 0 :(得分:85)
根据其他注释,第二个公用表表达式[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之前结束的语句......
但请注意,您的WHERE
语句存在第二个语法问题。 WHERE date IN table_2
无效,因为您实际上从未实际引用table_2中的值/列。我更喜欢INNER JOIN
而不是IN
或Exists
,所以这里的语法应该适用于JOIN
:
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
;
如果你想保持你拥有它的方式,通常EXISTS会优于IN,但要使用IN,你需要在你的位置使用实际的SELECT语句。
SELECT *
FROM
table_1 t1
WHERE t1.date IN (SELECT date FROM table_2);
当date
可能NULL
时, IN非常有问题,所以如果您不想使用JOIN
,我会建议EXISTS
。如下:
SELECT *
FROM
table_1 t1
WHERE EXISTS (SELECT * FROM table_2 t2 WHERE t2.date = t1.date);
答案 1 :(得分:7)
您还可以使用WITH语句链接结果。 例如:
WITH tab1 as (Your SQL statement),
tab2 as ( SELECT ... FROM tab1 WHERE your filter),
tab3 as ( SELECT ... FROM tab2 WHERE your filter)
SELECT * FROM tab3;