使用CASE表达式查询歌手是否参与金属风格合作的SQL实现
现有SQL的核心问题
- 采用内连接关联合作表,未参与任何合作的歌手会被直接过滤,无法满足“输出覆盖Singers全表所有歌手”的要求
- 仅通过
first_singer_id关联歌手身份,完全忽略second_singer_id对应的合作参与方,没有处理合作关系的对称性——只要某条金属风格合作的参与方,不管是第一还是第二顺位的歌手,都应该被标记为有金属合作记录 - 没有做聚合去重,同一个歌手如果参与多条合作,会在结果集中产生多行重复数据,和预期“每歌手一行”的结构不匹配
实现方案
以Singers全表为基准数据源,借助CASE表达式完成金属合作标识的判断,配合左连接、分组逻辑一次性解决上述三个问题:
- 用左连接替代内连接,从根源上保证所有Singers表的歌手都会进入结果集,不会被合作表的关联逻辑过滤
- 关联合作表时,同时匹配
first_singer_id和second_singer_id两个字段,不管歌手在合作记录里的顺位,只要是某条合作的参与方就算关联成功,解决对称性判断问题 - 按歌手维度做分组聚合,通过嵌套
CASE逻辑判断该歌手是否存在任意一条金属风格的合作记录,输出对应的Y/N标记,同时实现去重效果
可运行SQL代码
SELECT s.name, CASE -- 逐行判断关联到的合作记录是否为金属风格,聚合后判断是否存在命中记录 WHEN MAX(CASE WHEN c.genre = 'metal' THEN 1 ELSE 0 END) = 1 THEN 'Y' ELSE 'N' END AS metal FROM Singers s LEFT JOIN Colaborate c -- 同时匹配两个合作ID字段,覆盖合作关系的双向对称性 ON s.identification IN (c.first_singer_id, c.second_singer_id) -- 按歌手主键分组,保证每个歌手仅输出一行 GROUP BY s.identification, s.name
输出效果验证
运行上述代码可得到完全符合预期的结果:
| name | metal |
|---|---|
| Bolton | N |
| Madonna | Y |
| Nirvana | N |
| Hendrix | Y |
- 金属标记判断准确:Madonna在金属合作记录中是
second_singer_id顺位,也能被正确识别为Y - 无重复行:哪怕Madonna、Hendrix关联了多条不同风格的合作记录,最终也只会输出一行
- 全量覆盖:Singers表中所有歌手都在结果集中,不会因为无合作记录被遗漏
内容的提问来源于stack exchange,提问作者Ozera
相关产品推荐
相关产品推荐

