MySQL如何仅当另一张表所有行满足条件时更新目标表?
MySQL 按关联表全量条件更新实现方案
当然可以实现这个需求,你的CASE语句思路是对的,核心是通过子查询判断关联的TableB所有行是否都满足total == progress。以下是两种可行的实现方式:
方法一:用NOT EXISTS判断(推荐)
这种方式效率更高,因为一旦找到不满足条件的行就会停止查询:
UPDATE TableA SET completed = CASE WHEN NOT EXISTS ( -- 检查是否存在关联的TableB行不满足total=progress SELECT 1 FROM TableB WHERE TableB.tableA_id = TableA.id AND TableB.total != TableB.progress ) THEN 1 ELSE 0 END WHERE id = x; -- 替换x为目标TableA的id,去掉WHERE可批量更新所有TableA记录
原理:如果不存在任何一条关联的TableB记录不符合total == progress,就说明所有关联记录都满足条件,此时将completed设为1,否则设为0。
方法二:用COUNT对比行数
通过统计关联TableB的总行数和满足条件的行数,若两者相等则说明所有行都符合要求:
UPDATE TableA SET completed = CASE WHEN ( SELECT COUNT(*) FROM TableB WHERE TableB.tableA_id = TableA.id ) = ( SELECT COUNT(*) FROM TableB WHERE TableB.tableA_id = TableA.id AND TableB.total = TableB.progress ) THEN 1 ELSE 0 END WHERE id = x;
注意:如果TableB中没有对应TableA.id的记录,这种写法会把completed设为1(因为两个COUNT结果都是0)。如果需要这种场景下设为0,可以在CASE条件里额外加判断:
WHEN ( SELECT COUNT(*) FROM TableB WHERE TableB.tableA_id = TableA.id ) > 0 AND ( SELECT COUNT(*) FROM TableB WHERE TableB.tableA_id = TableA.id ) = ( SELECT COUNT(*) FROM TableB WHERE TableB.tableA_id = TableA.id AND TableB.total = TableB.progress ) THEN 1 ELSE 0
内容的提问来源于stack exchange,提问作者Michele Grisafi
相关产品推荐
相关产品推荐

