避免重复而不创建视图

Asl*_*986 3 postgresql cte

假设我有一个查询 Q1,我需要运行如下查询:

Q1
union
select *
from (some query that uses Q1 outcome)
Run Code Online (Sandbox Code Playgroud)

我想这样做:

  • 不创建任何视图
  • 无需运行两次 Q1 查询。

我怎样才能在 PostgreSQL 上做到这一点?

ype*_*eᵀᴹ 6

您可以为此使用通用表表达式:

WITH q1 AS
  ( SELECT ... )  
SELECT *
  FROM q1
UNION 
SELECT *
  FROM (some query that uses q1 outcome)
;
Run Code Online (Sandbox Code Playgroud)

甚至:

WITH q1 AS
  ( SELECT ... )  
TABLE q1
UNION 
SELECT *
  FROM (some query that uses q1 outcome)
;
Run Code Online (Sandbox Code Playgroud)

您还可以按顺序使用多个 CTE:

WITH q1 AS
  ( SELECT ... )
  , q2 AS
  (some query that uses q1 outcome)  
  , q3 AS
  (some other query that uses q1 and/or q2 outcome)  
SELECT *
  FROM q1
UNION 
SELECT *
  FROM q2
UNION 
SELECT q3.*
  FROM q2 JOIN q3 ON ...
;
Run Code Online (Sandbox Code Playgroud)

没有创建视图,也没有运行 Q1 查询的两次 - 好吧,这取决于实现。实际遵循的执行路径取决于优化器和其他几个因素。查询更加紧凑和优雅,但这并不意味着它比扩展它更有效。

  • +1 很好的答案。从 9.1 版开始,这也适用于 `INSERT`/`UPDATE`/`DELETE` 命令([Data-Modifying or Writable CTE](http://www.postgresql.org/docs/current/interactive/queries-with .html#QUERIES-WITH-MODIFYING。顺便说一句:OP 很有可能想要 [`UNION ALL`](http://www.postgresql.org/docs/current/interactive/sql-select.html #SQL-UNION) 而不是`UNION`。 (2认同)