如何在一个 PostgreSQL 查询中使用多个 WITH 语句?
How to use multiple WITH statements in one PostgreSQL query?
我想 "declare" 什么是使用 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
语句但无法找到答案。
根据其他评论,第二个 Common Table Expression [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 服务器人员(包括我自己)不会结束需要在定义 CTE 之前结束的先前语句...
但是请注意,您的 WHERE
语句存在第二个语法问题。 WHERE date IN table_2
无效,因为您从未实际引用 table_2 中的 value/column。我更喜欢 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,您需要在您的 where 中添加实际的 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);
您还可以使用 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;
我想 "declare" 什么是使用 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
语句但无法找到答案。
根据其他评论,第二个 Common Table Expression [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 服务器人员(包括我自己)不会结束需要在定义 CTE 之前结束的先前语句...
但是请注意,您的 WHERE
语句存在第二个语法问题。 WHERE date IN table_2
无效,因为您从未实际引用 table_2 中的 value/column。我更喜欢 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,您需要在您的 where 中添加实际的 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);
您还可以使用 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;