我有3个表A(a1,a2),B(b1,b2),C(c1,c2)。我想以下列方式执行更新:
UPDATE A
SET A.a2 = (SELECT 2* SUM(C.c2)
FROM B JOIN C
ON B.b1 = C.c1 WHERE A.a1 = B.b2)
WHERE A.a1 = (SELECT B.b2
FROM B JOIN C
ON B.b1 = C.c1 HAVING SUM(C.c2) > 1000);
这种方法的问题是表B和C需要连接多次。
有什么好的解决方案可以解决这个问题吗?
我试过了:
UPDATE A SET A.a2 = (SELECT CASE
WHEN SUM(C.c2) > 1000 THEN 2*SUM(C.c2)
ELSE A.a2
END
FROM B JOIN C
ON B.b1 = C.c1
WHERE A.a1 = B.b2);
但它不使用a1上的索引,它也会更新表A中的所有行,这比原来的行还要慢
答案 0 :(得分:1)
使用MERGE
代替时,这种更新通常会更快:
MERGE INTO a
using
(
SELECT b.b2, 2 * SUM(C.c2) as c2_sum
FROM B
JOIN C ON B.b1 = C.c1
group by b.b2
HAVING SUM(C.c2) > 1000
) t on (t.b2 = a.a1)
when matched then update
set a2 = t.c2_sum;
答案 1 :(得分:0)
如果它的操作非常长,您可以创建计算结果的中间表。但是你需要在两个表上都有主键
Create table int_a as
SELECT 2* SUM(C.c2) as new_a2
, B.b2
FROM B JOIN C
ON B.b1 = C.c1 WHERE A.a1 = B.b2
GROUP BY B.b2
HAVING SUM(C.c2) > 1000
alter table int_a add constraint primary key pk_int_a (b2);
alter table a add constraint primary key pk_a (a2);
并使用join
更新表a update (select a2, int_a.new_a2
from A, INT_A
where A.a1 = INT_A.b2)
set a2 = new_a2
答案 2 :(得分:0)
您可以使用“with clause”
update A
SET A.a2 =
((with data as (SELECT B.b2, C.c2 FROM B JOIN C ON B.b1 = C.c1)
select *
from data_b_c)
select * from data b_c, A where A.a1 = b_c.b2 HAVING SUM(b_c.c2) > 1000)