基本答案
有CTEs (Common Table Expressions) in Postgres(就像在除 MySQL 之外的任何主要现代 RDBMS 中一样)。从包含 data-modifying CTEs 的 9.1 版开始。这些可以“嵌套”。
更新:MySQL 8.0 finally adds CTEs.
与子查询不同的是,CTE 构成了优化障碍。查询规划器不能将琐碎的命令内联到主命令中或重新排序主查询和 CTE 之间的连接。子查询也是如此。对性能可能(非常)好或(非常)坏,这取决于。
无论哪种方式,CTE 都需要比子查询更多的开销(性能成本)。
更新:Postgres 12 终于可以在主查询中inline plain CTEs。
您没有要求的详细信息
你的问题很基础,上面的回答大概就够了。但我会为高级用户添加一些内容(以及显示语法的代码示例)。
查询的所有 CTE 都基于数据库的相同快照。下一个 CTE 可以重用以前 CTE(内部临时表)的输出,但对其他 CTE 的基础表的影响是不可见的。多个 CTE 的序列是任意的除非通过 INSERT、UPDATE、DELETE 的 RETURNING 子句返回某些内容 - 与 SELECT 无关,因为它不会改变任何内容并且只是从快照中读取。
这可能会对影响同一行的多个更新产生微妙的影响。只有 一个 更新可以影响每一行。哪个受 CTE 序列的影响。
尝试预测结果:
CREATE TEMP TABLE t (t_id int, txt text);
INSERT INTO t VALUES (1, 'foo'), (2, 'bar'), (3, 'baz');
WITH sel AS (SELECT * FROM t)
, up1 AS (UPDATE t SET txt = txt || '1' WHERE t_id = 1 RETURNING *)
, up2 AS (UPDATE t SET txt = t.txt || '2'
FROM up1
WHERE up1.t_id = t.t_id
RETURNING t.*)
, ins AS (INSERT INTO t VALUES (4, 'bamm'))
, up3 AS (UPDATE t SET txt = txt || '3' RETURNING *)
SELECT 'sel' AS source, * FROM sel
UNION ALL
SELECT 'up1' AS source, * FROM up1
UNION ALL
SELECT 'up2' AS source, * FROM up2
UNION ALL
SELECT 'up3' AS source, * FROM up3
UNION ALL
SELECT 't' AS source, * FROM t;
SQL Fiddle
不要失望,我怀疑这里有很多人可以做到。 :)
要点:避免 CTE 中的冲突命令。