SQL 分组并仅保留包含给定列值的那些组

SQL group by and keep only those groups that include given value of column

我有一个 songs table、一个 lyrics table 和一个 tags table。一首歌可能有多个歌词(或 none),每个歌词只有一个标签。因此,在 lyrics table 中我有两个外键,song_idtag_id,它们都链接到各自 table 中的记录。

我想 select 所有 没有 的歌曲都有 given 标签。例如,给定以下视图(三个 table 是 INNER JOINed):

song_id | lyric_id | tag_id | tag_value
---------------------------------------
1       | 1        | 1      | 'pop'
1       | 2        | 2      | 'hip-hop'
2       | 3        | 1      | 'pop'

给定 'hip-hop' 标签,我需要检索第二首歌曲,因为它没有链接的歌词,而链接的标签具有 'hip-hop' 值。

如果我给出 'pop' 标签,将不会检索到任何歌曲,因为两首歌都有链接了 'pop' 标签的歌词。

如何以最佳方式构建这样的查询?我正在考虑按 song_id 分组,然后执行 HAVING(tag_value != 'hip-hop'),但不幸的是,这不是 HAVING 的工作方式。

这是 [not] exists 运算符的经典用例:

SELECT *
FROM   songs s
WHERE  NOT EXISTS (SELECT *
                   FROM   lyrics l
                   JOIN   tags t ON l.tag_id = t.id
                   WHERE  l.song_id = s.id AND 
                          t.tag_value = 'hip-hop') -- or any other tag