是否可以将非选择查询(更新,插入,删除)嵌入到另一个查询中?
类似(选择中的插入)
A single query:
select such,and,such from .... where .... insert into .... ;
答案 0 :(得分:5)
有CTEs (Common Table Expressions) in Postgres(与MySQL之外的任何主要现代RDBMS一样)。从版本9.1开始,包括data-modifying CTEs。那些可以“嵌套” 更新:MySQL 8.0 finally adds CTEs.
与子查询不同,CTE构成优化障碍。查询计划程序无法将简单命令内联到主命令或重新排序主查询和CTE之间的连接。子查询也是如此。可能(非常)好或(非常)不利于表现,这取决于 无论哪种方式,CTE都需要比子查询更多的开销(性能成本)。
你的问题很基本,上面的内容可能足以回答。但我会为高级用户添加一些内容(以及显示语法的代码示例)。
查询的所有CTE都基于数据库的相同快照。下一个CTE可以重用以前CTE的输出(内部临时表),但对其他CTE不可见对基础表的影响。多个CTE的序列是任意的,除非返回RETURNING
INSERT
UPDATE
,DELETE
,SELECT
的一些内容 - {{1}的irrelvant因为它不会改变任何东西而只是从快照中读取。
这会对影响同一行的多个更新产生微妙的影响。只有一个更新可以影响每一行。哪一个受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;
不要失望,我怀疑这里有很多人可以做到。 :)
其中的要点是:避免在CTE中发生冲突的命令。