[英]Postgres SQL UPDATE based on result of a previous SELECT
In Postgres 10 I want to perform an UPDATE twice. 在Postgres 10中,我想要执行两次UPDATE。 First UPDATE should run no matter what, updating the alwaysupdate
column. 无论如何都要运行第一个UPDATE,更新alwaysupdate
列。 And the second UPDATE should run only if the SELECT statement below returns a row count of 0, which means sometimesupdate
should get updated only if all of the rows in mytable
where mykey = 100
have sometimesupdate
set to null
. 但第二个更新应该只运行,如果下面的SELECT语句返回0行数,这意味着sometimesupdate
应该得到更新只有当所有的行mytable
其中mykey = 100
已经sometimesupdate
设置为null
。
-- Run no matter what, updating 'alwaysupdate'
update mytable set alwaysupdate = now() where keyA = 100 and keyB = 200
-- Check the number of rows where 'sometimesupdate' has a value
select count(*) from mytable where keyB = 200 and sometimesupdate is not null
-- If 'sometimesupdate' is null for all rows above, give it a value in this row
update mytable set sometimesupdate = now() where keyA = 100 and keyB = 200
What's the most efficient way to do this? 最有效的方法是什么? Is it possible to combine it into a single SQL statement? 是否可以将它组合成一个SQL语句? Otherwise multiple statements wrapped in a transaction? 否则多个语句包含在一个事务中? Otherwise a function if necessary. 如有必要,否则为其他功能
Try this 尝试这个
if count is equal to zero then update to now() otherwise retain the old value of sometimesupdate 如果count等于零,则更新到now()否则保留onceupdate的旧值
update mytable as A
set alwaysupdate = now(),
sometimesupdate = (case when (
select count(*) from mytable as B where B.keyB = A.keyB
and sometimesupdate is not null) = 0
then now()
else sometimesupdate end)
where keyA = 100 and keyB = 200
or if you want to update that specific row which has no sometimesupdate and is keyb = 200 then do below 或者如果你想更新那个没有有时更新并且keyb = 200的特定行,那么在下面做
UPDATE mytable
SET alwaysupdate = now(),
sometimesupdate = (CASE
WHEN keyB = 200 THEN CASE
WHEN sometimesupdate IS NULL THEN now()
ELSE sometimesupdate
END
ELSE sometimesupdate
END)
WHERE keyA = 100
AND keyB = 200
One method puts the logic in the from
clause: 一种方法将逻辑放在from
子句中:
update mytable
set alwaysupdate = now(),
sometimesupdate = (case when b.cnt = 0 then now() else sometimesupdate end)
from (select count(*) from mytable where keyB = 200 and sometimesupdate is not null
) b
where keyA = 100 and keyB = 200;
However, not exists
would usually have better performance: 但是, not exists
通常会有更好的性能:
update mytable
set alwaysupdate = now(),
sometimesupdate = (case when not exists (select 1 from mytable where keyB = 200 and sometimesupdate is not null)
then now()
end)
) b
where keyA = 100 and keyB = 200;
You can use a chained CTE, and make the second update conditional on an EXISTS(...)
[NOT EXISTS() is the same as COUNT()==zero] 您可以使用链式CTE,并使第二次更新以EXISTS(...)
条件EXISTS(...)
[NOT EXISTS()与COUNT()== 0]相同
-- Run no matter what, updating 'alwaysupdate'
WITH u1 AS (
UPDATE mytable
SET alwaysupdate = now()
WHERE keyA = 100 AND keyB = 200;
RETURNING *
)
UPDATE mytable u2
SET sometimesupdate = now()
FROM u1
WHERE u1.keyA = u2.keyA -- 100
AND u1.keyB = u2.keyB -- 200
-- If 'sometimesupdate' is null for all rows below, give it a value in this row
-- Check if there are any rows where 'sometimesupdate' has a value
AND NOT EXISTS (SELECT *
FROM mytable nx
WHERE nx.keyB = u2.keyB -- 200
AND sometimesupdate IS NOT NULL
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.