多条件删除记录:剔除bid_account表指定条件下的重复竞价记录
删除bid_account表中特定条件下的重复记录
没问题,我来帮你搞定这个重复记录清理的需求。根据你描述的规则,我们需要从bid_account表中移除满足以下所有条件的重复条目:
bid_flag必须等于'd'bidding_type必须等于's'- 同一个
auction_id(商品ID)下,bidding_price不能有重复值
核心思路是:先识别出每个auction_id+bidding_price组里的重复记录,然后保留其中一条(通常按主键id来决定留最新或最早的),删除其余重复项。下面分主流数据库给出具体方案:
MySQL 解决方案
方法1:自连接删除(适合所有MySQL版本)
这种写法兼容性好,通过自连接匹配重复项,然后删除主键较小的那条(如果你想保留最早的,把<改成>就行):
DELETE ba1 FROM bid_account ba1 JOIN bid_account ba2 ON ba1.auction_id = ba2.auction_id AND ba1.bidding_price = ba2.bidding_price AND ba1.id < ba2.id WHERE ba1.bid_flag = 'd' AND ba1.bidding_type = 's' AND ba2.bid_flag = 'd' AND ba2.bidding_type = 's';
方法2:窗口函数删除(MySQL 8.0+)
如果你的MySQL版本是8.0及以上,用窗口函数更直观,能清晰标记重复项:
DELETE FROM bid_account WHERE id IN ( SELECT id FROM ( SELECT id, ROW_NUMBER() OVER ( PARTITION BY auction_id, bidding_price ORDER BY id DESC -- 按id降序,保留最新的记录;改成ASC则保留最早的 ) AS rn FROM bid_account WHERE bid_flag = 'd' AND bidding_type = 's' ) AS sub_query WHERE rn > 1 -- 只删除编号大于1的重复项 );
PostgreSQL 解决方案
PostgreSQL的写法和MySQL 8.0+的窗口函数方案类似,也支持自连接写法:
窗口函数写法
DELETE FROM bid_account WHERE id IN ( SELECT id FROM ( SELECT id, ROW_NUMBER() OVER ( PARTITION BY auction_id, bidding_price ORDER BY id DESC ) AS rn FROM bid_account WHERE bid_flag = 'd' AND bidding_type = 's' ) AS sub_query WHERE rn > 1 );
自连接写法
DELETE FROM bid_account ba1 USING bid_account ba2 WHERE ba1.auction_id = ba2.auction_id AND ba1.bidding_price = ba2.bidding_price AND ba1.id < ba2.id AND ba1.bid_flag = 'd' AND ba1.bidding_type = 's' AND ba2.bid_flag = 'd' AND ba2.bidding_type = 's';
重要注意事项
- 先备份再操作:删除数据前一定要先备份表,或者把
DELETE换成SELECT *先验证要删除的记录是否正确,避免误删! - 加索引提升效率:如果表数据量很大,建议给
auction_id、bidding_price、bid_flag、bidding_type建联合索引,能大幅加快查询和删除速度:
-- MySQL/PostgreSQL通用索引语句 CREATE INDEX idx_bid_account_auction_price_flag_type ON bid_account(auction_id, bidding_price, bid_flag, bidding_type);
- 按需调整保留规则:如果业务需要保留特定的记录(比如最早录入的),只需要修改
ORDER BY子句的排序方向即可。
内容的提问来源于stack exchange,提问作者Clebson
相关产品推荐
相关产品推荐

