Label值为Error时删除对应PaymentId所有行的SQL实现
需求说明
若表中任意记录的Label字段值为'Error',需全部删除该记录对应PaymentId关联的所有行。
测试表初始化脚本
CREATE TABLE Test (Id INT, PaymentId INT, Label VARCHAR(25)); INSERT INTO Test VALUES (1, 22, 'Error'), (2, 22, 'Seattle'), (3, 22, 'Pending'), (4, 33, 'Paid'), (5, 33, 'Los Angeles'), (6, 44, 'Houston'), (7, 44, 'Error'), (8, 55, 'Pending'), (9, 55, 'San Diego'), (10, 55, 'Authorization') SELECT * FROM Test
初始数据预览
| Id | PaymentId | Label |
|---|---|---|
| 1 | 22 | Error |
| 2 | 22 | Seattle |
| 3 | 22 | Pending |
| 4 | 33 | Paid |
| 5 | 33 | Los Angeles |
| 6 | 44 | Houston |
| 7 | 44 | Error |
| 8 | 55 | Pending |
| 9 | 55 | San Diego |
| 10 | 55 | Authorization |
标注*的PaymentId 22、44是存在Error标签、需要全量删除的分组
预期执行结果
执行删除后,仅保留无Error标签的PaymentId 33、55对应的记录:
| Id | PaymentId | Label |
|---|---|---|
| 4 | 33 | Paid |
| 5 | 33 | Los Angeles |
| 8 | 55 | Pending |
| 9 | 55 | San Diego |
| 10 | 55 | Authorization |
注:原需求描述中预期结果最后一行的Id=9、Label=Seattle为笔误,Seattle属于待删除的PaymentId=22分组,不会出现在最终结果中。
实现语句
通用写法(支持PostgreSQL、SQL Server、Oracle等主流数据库)
核心逻辑是先匹配所有带Error标签的PaymentId,再删除这些Id对应的全部记录:
DELETE FROM Test WHERE PaymentId IN ( SELECT PaymentId FROM Test WHERE Label = 'Error' );
MySQL兼容写法
MySQL不支持DELETE操作中子查询直接引用同表,需要给子查询嵌套一层派生表绕过语法限制:
DELETE FROM Test WHERE PaymentId IN ( SELECT t.PaymentId FROM ( SELECT PaymentId FROM Test WHERE Label = 'Error' ) t );
执行后即可得到符合要求的结果。
内容的提问来源于stack exchange,提问作者Yara1994
相关产品推荐
相关产品推荐

