我在PostgreSQL中有一个复杂的查询,我想在UPDATE和DELETE等其他操作中使用它的结果,如:
<COMPLEX QUERY>;
UPDATE WHERE <COMPLEX QUERY RESULT> = ?;
DELETE WHERE <COMPLEX QUERY RESULT> = ?;
UPDATE WHERE <COMPLEX QUERY RESULT> = ?;
我不希望每次操作都要进行一次复杂查询。避免这种情况的一种方法是将结果存储在表中并将其用于WHERE和JOINS,并在完成后删除临时表。
我想知道是否有其他方法没有将结果存储到数据库,但已经在内存中使用结果。
我已经为此使用了循环,但我认为每件事只做一次操作比每行操作要快。
答案 0 :(得分:2)
如果查询的结果类型与任何现有的查询不匹配,您可以遍历查询结果,如@phatfingers演示(可能使用通用record
变量或标量变量而不是rowtype
行类型)。对于少量结果行或顺序处理是必要的,这是一个好主意。
对于大结果集,您的原始方法的执行速度会快一个数量级。使用一个SQL命令进行批量INSERT / UPDATE / DELETE要便宜得多 而不是逐步写入/删除,一次一行。
临时表是重用此类结果的正确选择。它会在会话结束时自动删除。如果您想立即删除它或在事务结束时删除它,您只需要明确删除。我引用manual here:
临时表会在会话结束时自动删除,或者 可选地在当前交易结束时。
对于大型临时表,在填充ANALYZE
之后运行它是个好主意。
以下是Pavel在评论中添加的演示:
CREATE TEMP TABLE t1(id serial, txt text);
INSERT INTO t1(txt)
VALUES ('foo'), ('bar'), ('baz'), ('bax');
CREATE TEMP TABLE t2(id serial, txt text);
INSERT INTO t2(txt)
VALUES ('foo2'),('bar2'),('baz2');
CREATE TEMP TABLE t3 (id serial, txt text);
WITH x AS (
UPDATE t1
SET txt = txt || '2'
WHERE txt ~~ 'ba%'
RETURNING txt
)
, y AS (
DELETE FROM t2
USING x
WHERE t2.txt = x.txt
RETURNING *
)
INSERT INTO t3
SELECT *
FROM y
RETURNING *;
请阅读手册中的Data-Modifying Statements in WITH一章。
答案 1 :(得分:1)
DECLARE
r foo%rowtype;
BEGIN
FOR r IN [COMPLEX QUERY]
LOOP
-- process r
END LOOP;
RETURN;
END