MySQL查询问题:如何筛选无Payment_GP类型的关联交易
问题描述
现有三张业务表:
- Table A:交易主表,存储主交易核心信息
- Table B:关联交易记录表,每条主交易对应多条关联交易记录
- Table C:关联交易类型表,存储关联交易的类型名称
需求:提取所有未关联Payment_GP类型的主交易及其全部关联交易。注意:如果某条主交易的任意一条关联交易类型为Payment_GP,该主交易的所有关联交易都需排除(比如主交易ID=1关联了Payment_GP类型的记录,那么ID=1的所有关联交易都不能返回)。
表数据
Table A(交易主表)
| ID | Name |
|---|---|
| 1 | Trade1 |
| 2 | Trade2 |
| 3 | Trade3 |
Table B(关联交易记录表)
| Rel_ID | Main_ID | Type_ID |
|---|---|---|
| A | 1 | 1 |
| B | 1 | 2 |
| C | 2 | 1 |
| D | 1 | 3 |
| E | 3 | 2 |
Table C(关联交易类型表)
| Type_ID | Type_Name |
|---|---|
| 1 | Payment_CC |
| 2 | Transfer |
| 3 | Payment_GP |
预期输出
| Main_ID | Rel_ID | Type_Name |
|---|---|---|
| 2 | C | Payment_CC |
| 3 | E | Transfer |
现有未达预期的查询语句
SELECT a.ID AS Main_ID, b.Rel_ID, c.Type_Name FROM TableA a JOIN TableB b ON a.ID = b.Main_ID JOIN TableC c ON b.Type_ID = c.Type_ID WHERE c.Type_Name != 'Payment_GP';
问题排查与解决
原有查询的问题
原有查询仅排除了单条Payment_GP类型的关联记录,但没有排除整个存在Payment_GP关联的主交易——比如主交易ID=1虽然有Payment_GP的记录,但原有查询会返回ID=1的其他非Payment_GP关联记录,不符合需求。
正确查询语句
先筛选出完全没有Payment_GP关联的主交易ID,再关联获取对应的关联交易记录:
SELECT a.ID AS Main_ID, b.Rel_ID, c.Type_Name FROM TableA a JOIN TableB b ON a.ID = b.Main_ID JOIN TableC c ON b.Type_ID = c.Type_ID WHERE a.ID NOT IN ( SELECT DISTINCT b.Main_ID FROM TableB b JOIN TableC c ON b.Type_ID = c.Type_ID WHERE c.Type_Name = 'Payment_GP' );
逻辑说明
- 子查询先找出所有关联过Payment_GP类型的主交易ID集合
- 主查询只保留不在该集合内的主交易,再关联获取它们的所有关联交易
- 确保返回的主交易完全没有Payment_GP类型的关联,符合需求
也可以用LEFT JOIN的写法实现相同效果:
SELECT a.ID AS Main_ID, b.Rel_ID, c.Type_Name FROM TableA a JOIN TableB b ON a.ID = b.Main_ID JOIN TableC c ON b.Type_ID = c.Type_ID LEFT JOIN ( SELECT DISTINCT Main_ID FROM TableB JOIN TableC ON TableB.Type_ID = TableC.Type_ID WHERE Type_Name = 'Payment_GP' ) bad_trades ON a.ID = bad_trades.Main_ID WHERE bad_trades.Main_ID IS NULL;
内容的提问来源于stack exchange,提问作者SSK
相关产品推荐
相关产品推荐

