是否可以在没有多个 CASE 块的情况下解决这个问题?
这是我到目前为止所得到的:我已经为此工作了几个小时,并且不知道如何在不重复 CASE 语句并一次设置一个的情况下做到这一点。这是我得到的:
UPDATE my_table
SET (status, mined_at) = CASE
WHEN id <= $1 AND status <> $2 AND status <> $3
THEN ($2, CURRENT_TIMESTAMP)
WHEN id > $1
THEN ($4, NULL)
ELSE (status, mined_at)
END
非常感谢任何帮助。
您可能应该在 index
上有一个
id
,并针对不同 update
语句中的不同行。
CREATE INDEX ON my_table (id);
UPDATE my_table
SET (status, mined_at) = ($2, CURRENT_TIMESTAMP)
WHERE id <= $1 AND status NOT IN ($2,$3);
UPDATE my_table
SET (status, mined_at) = ($4, NULL)
WHERE id > $1;
ROW EXCLUSIVE
锁 不会发生冲突。因此,它们可以并行运行,使它们的总执行时间大约是完成较长部分所需的时间。case
更好。
如果您的情况听起来像上面的第 3 点,您必须修复语法:
UPDATE my_table
SET (status, mined_at)=(CASE WHEN id <= $1 AND status <> $2 AND status <> $3
THEN $2
WHEN id > $1
THEN $4
ELSE status
END,
CASE WHEN id <= $1 AND status <> $2 AND status <> $3
THEN CURRENT_TIMESTAMP
WHEN id > $1
THEN NULL
ELSE mined_at
END);
或者
UPDATE my_table
SET status=CASE WHEN id <= $1 AND status <> $2 AND status <> $3
THEN $2
WHEN id > $1
THEN $4
ELSE status
END,
mined_at=CASE WHEN id <= $1 AND status <> $2 AND status <> $3
THEN CURRENT_TIMESTAMP
WHEN id > $1
THEN NULL
ELSE mined_at
END;
否则你会得到一个错误
ERROR: source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression LINE 2: SET (status, mined_at) = CASE ^