如何交换复合主键包含的bill_portal列的对应值?
如何交换组合主键表中同一bill_id下的bill_portal值
针对你这个场景——同一bill_id下两行数据的bill_portal值互换,同时保留对应amount和currency不变——有两种简单实用的实现方式,我给你详细说明:
方法一:使用CASE语句直接替换(适合固定值交换)
如果你的场景里,需要交换的bill_portal值是固定的(比如例子里的10和20),用CASE语句最直观,代码也简洁:
首先可以先验证替换后的结果是否符合预期:
SELECT bill_id, CASE bill_portal WHEN 10 THEN 20 WHEN 20 THEN 10 ELSE bill_portal -- 保留其他bill_portal值不变 END AS bill_portal, amount, currency FROM bill WHERE bill_id = 100;
确认结果正确后,执行更新操作:
UPDATE bill SET bill_portal = CASE bill_portal WHEN 10 THEN 20 WHEN 20 THEN 10 ELSE bill_portal END WHERE bill_id = 100;
这个方法的好处是逻辑清晰,容易理解,适合只有特定两个值需要交换的场景。
方法二:使用自连接更新(通用场景)
如果同一bill_id下可能有更多行需要交换,或者bill_portal的值不固定,自连接的方法更通用,它会自动匹配同一bill_id下的不同行来交换bill_portal值:
同样先验证结果:
SELECT b1.bill_id, b2.bill_portal AS new_bill_portal, b1.amount, b1.currency FROM bill b1 JOIN bill b2 ON b1.bill_id = b2.bill_id AND b1.bill_portal != b2.bill_portal WHERE b1.bill_id = 100;
然后执行更新(以MySQL为例,不同数据库语法可能略有差异,比如PostgreSQL需要用FROM子句或者CTE):
UPDATE bill b1 JOIN bill b2 ON b1.bill_id = b2.bill_id AND b1.bill_portal != b2.bill_portal SET b1.bill_portal = b2.bill_portal, b2.bill_portal = b1.bill_portal WHERE b1.bill_id = 100;
注意事项
- 执行更新操作前,一定要先备份数据或者用SELECT语句验证结果,避免误操作;
- 如果是全表处理所有
bill_id下的行,去掉WHERE子句即可,但要确保每个bill_id下的行是成对的(否则可能出现重复值冲突,因为主键是bill_id+bill_portal)。
内容的提问来源于stack exchange,提问作者Praroop Khare
相关产品推荐
相关产品推荐

