SQL一对多关联查询:嵌套IF的CASE语句会员等级匹配问题
原SQL的问题
- 语法不兼容:SELECT子句里不能直接用
IF ... THEN ...的流程控制写法,这类判断直接用CASE WHEN即可,不需要额外嵌套IF - 关联会产生重复行:隐式内连接会把一个账号下所有表B的记录都关联出来,比如账号345在表B有2条记录,最终就会返回2行345的数据,不符合你一行表A记录对应一行结果的需求
- 默认返回值错误:你写的无匹配返回值是'Non Member',和需求要求的'Not Included'不一致
可直接运行的正确SQL
SELECT a.num_seats, a.num_seats_attended, a.acct_id, a.owner_name, COALESCE( MAX( CASE WHEN b.membership_id = 10 THEN 'Type A' WHEN b.membership_id = 11 THEN 'Type B' WHEN b.membership_id = 12 THEN 'Type C' WHEN b.membership_id = 13 THEN 'Type D' WHEN b.membership_id = 14 THEN 'Type E' WHEN b.membership_id = 15 THEN 'Type F' WHEN b.membership_id = 16 THEN 'Type G' WHEN b.membership_id = 17 THEN 'Type H' WHEN b.membership_id = 18 THEN 'Type I' WHEN b.membership_id = 19 THEN 'Type J' WHEN b.membership_id = 20 THEN 'Type K' WHEN b.membership_id = 21 THEN 'Type L' WHEN b.membership_id = 22 THEN 'Type M' WHEN b.membership_id = 23 THEN 'Type N' WHEN b.membership_id = 24 THEN 'Type O' WHEN b.membership_id = 25 THEN 'Type P' WHEN b.membership_id = 740 THEN 'Type Q' END ), 'Not Included' ) AS membership_level FROM table_a a LEFT JOIN table_b b ON a.acct_id = b.acct_id GROUP BY a.num_seats, a.num_seats_attended, a.acct_id, a.owner_name;
逻辑说明
- 用
LEFT JOIN做关联,保证表A的所有记录都会保留,不会因为表B没有匹配记录就丢失 - 所有会员ID的等级映射统一放在一个
CASE WHEN块中,不在指定ID列表里的记录会自动返回NULL - 用
MAX()聚合同一个账号下的匹配结果:只要账号存在任意一个在目标列表里的会员ID,就会返回对应的等级值;如果同一个账号有多个在列表里的会员ID,MAX()会取字符串排序最靠后的等级,你可以根据业务规则换成MIN()调整优先级 - 最后用
COALESCE()处理无匹配的场景,聚合结果为NULL时统一返回Not Included
用你提供的样例数据运行上述SQL,会完全返回你期望的结果:
| Num_Seats | Num_Seats_Attended | acct_id | owner_name | membership_level |
|---|---|---|---|---|
| 1 | 1 | 345 | J Doe | Type C |
| 2 | 1 | 673 | M Singh | Not Included |
| 1 | 0 | 354 | T Chong | Type D |
| 3 | 3 | 767 | F McDonald | Type Q |
| 1 | 1 | 768 | C Macron | Not Included |
内容的提问来源于stack exchange,提问作者Julie Dunsmuir
相关产品推荐
相关产品推荐

