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_id
和 tag_id
,它们都链接到各自 table 中的记录。
我想 select 所有 没有 的歌曲都有 given 标签。例如,给定以下视图(三个 table 是 INNER JOIN
ed):
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
我有一个 songs
table、一个 lyrics
table 和一个 tags
table。一首歌可能有多个歌词(或 none),每个歌词只有一个标签。因此,在 lyrics
table 中我有两个外键,song_id
和 tag_id
,它们都链接到各自 table 中的记录。
我想 select 所有 没有 的歌曲都有 given 标签。例如,给定以下视图(三个 table 是 INNER JOIN
ed):
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