如何在一个PostgreSQL查询中使用多个WITH语句?

Gre*_*reg 57 sql postgresql common-table-expression

我想使用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
Run Code Online (Sandbox Code Playgroud)

我已阅读PostgreSQL文档,并研究使用多个WITH语句,但无法找到答案.

Mat*_*att 100

根据其他注释,第二个公用表表达式[CTE]前面是逗号,而不是WITH语句

WITH cte1 AS (SELECT...)
, cte2 AS (SELECT...)
SELECT *
FROM
    cte1 c1
    INNER JOIN cte2 c2
    ON ........
Run Code Online (Sandbox Code Playgroud)

就你的实际查询而言,这种语法应该适用于PostgreSql,Oracle和sql-server,以后通常会继续WITH使用分号(;WTIH),但这是因为通常sql-server伙伴(包括我自己)不会结束以前的陈述需要在定义CTE之前结束......

但请注意,您的WHERE语句有第二个语法问题. WHERE date IN table_2无效,因为您实际上从未实际引用table_2中的值/列.我喜欢INNER JOININ或者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
;
Run Code Online (Sandbox Code Playgroud)

如果你想保持你拥有它的方式,通常EXISTS会优于IN,但要使用IN,你需要在你的位置使用一个实际的SELECT语句.

SELECT * 
FROM
     table_1 t1
WHERE t1.date IN (SELECT date FROM table_2);
Run Code Online (Sandbox Code Playgroud)

IN是非常有问题的,如果你不想使用当时date可能会NULL这样,JOIN我会建议EXISTS.如下:

SELECT * 
FROM
     table_1 t1
WHERE EXISTS (SELECT * FROM table_2 t2 WHERE t2.date = t1.date);
Run Code Online (Sandbox Code Playgroud)


Suz*_*tha 9

您还可以使用 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;
Run Code Online (Sandbox Code Playgroud)

  • 此上下文中的“过滤器”是“WHERE”子句的“条件”,即 SQL 布尔表达式。您可以在[文档](https://www.postgresql.org/docs/current/sql-select.html)和在线教程中查看详细信息和示例。使用测试数据库是一种很好的学习方法。 (2认同)