SQL多表关联查询不含Latin/Rock/Pop流派曲目的播放列表求助
原SQL存在的问题
- 条件语法错误:
WHERE g.Name <> "Latin " AND "Rock" AND "Pop"是无效的多值排除写法,SQL会将"Rock"、"Pop"作为布尔值判断,非空字符串会被判定为真,最终条件等价于g.Name <> "Latin ",且你在"Latin"后多写了空格,无法匹配到正确的流派名称。 - 逻辑不符合需求:你当前的查询逻辑是筛选出「存在至少一首不属于这三个流派的曲目」的播放列表,而非「完全不包含这三个流派任何曲目」的播放列表,哪怕播放列表同时有Rock和古典曲目,也会被你的查询命中,导致结果完全不符合预期。
- 内连接的局限性:空播放列表(没有关联任何曲目的播放列表)会被内连接直接过滤,如果你需要保留空播放列表的话需要调整关联逻辑。
正确查询语句
推荐用NOT EXISTS实现,逻辑最直观易读:
SELECT p.PlaylistId, p.Name FROM Playlist p WHERE NOT EXISTS ( SELECT 1 FROM PlaylistTrack pt INNER JOIN Track t ON pt.TrackId = t.TrackId INNER JOIN Genre g ON t.GenreId = g.GenreId WHERE pt.PlaylistId = p.PlaylistId AND g.Name IN ('Latin', 'Rock', 'Pop') )
如果更习惯用关联聚合的方式,也可以用如下写法:
SELECT p.PlaylistId, p.Name FROM Playlist p LEFT JOIN PlaylistTrack pt ON p.PlaylistId = pt.PlaylistId LEFT JOIN Track t ON pt.TrackId = t.TrackId LEFT JOIN Genre g ON t.GenreId = g.GenreId AND g.Name IN ('Latin', 'Rock', 'Pop') GROUP BY p.PlaylistId, p.Name HAVING COUNT(g.GenreId) = 0
两种写法都会返回完全没有Latin、Rock、Pop三个流派曲目的播放列表,和你给出的期望结果完全匹配。
内容的提问来源于stack exchange,提问作者rubengavidia0x
相关产品推荐
相关产品推荐

