2015-12-22 66 views
0

我正在使用標籤爲歌曲製作搜索引擎,並且我無法構建將列出與標籤匹配的所有歌曲的SQL查詢。查詢搜索歌曲以包含所有請求的標籤

數據庫看起來是這樣的: http://i.imgur.com/5zmfAz8.png

歌曲必須通過一箇中間表(SongTags)許多標籤。

讓我們人口爲例:

標籤: 電,器樂,精力充沛,憂鬱,人聲,搖滾

歌曲: SONGA(電,憂鬱,聲樂) 歌曲B (Instrumental,Melancholic,Rock) SongC(Energetic,Vocal)


搜索應返回包含所有請求標籤的歌曲。

搜索1:

「聲樂」 的回報:SONGA,歌曲B

搜索2:

「聲樂」, 「精力充沛」 的回報:SongC

Search3:

「美聲」,「精力充沛」,「電」返回:無


我看看怎麼做一個搜索1個標籤,但不能在多個標籤。 對於爲例的搜索1,我知道這會工作:

SELECT * FROM "songs" 
INNER JOIN "song_tags" ON "song_tags"."song_id" = "songs"."id" 
INNER JOIN "tags" ON "tags"."id" = "song_tags"."tag_id" 
WHERE "tags"."name" = 'Vocal' 

但後來我有我怎麼能執行搜索2不知道,因爲我需要的歌曲同時包含「聲樂」和「精力充沛」。

編輯:

我使用PostgreSQL

回答

0
SELECT songs.*, COUNT(songs.id) AS total FROM "songs" 
INNER JOIN "song_tags" ON "song_tags"."song_id" = "songs"."id" 
INNER JOIN "tags" ON "tags"."id" = "song_tags"."tag_id" 
WHERE "tags"."name" IN ('Vocal', 'Energetic') 
GROUP BY songs.id 
HAVING total = 2 
+0

完美的作品!謝謝你的回答! – Leoss

0

如果你想拿到賽提供你所有的標記,歌曲,我會使用子查詢。他們會有點慢,但它會給你一個全匹配的解決方案:

SELECT songs.* FROM songs 
    WHERE songs.song_id IN 
    (SELECT song_tags.song_id FROM song_tags st JOIN tags t ON st.tag_id = t.id AND t.name = 'VOCAL') 
    AND songs.song_id IN (SELECT song_tags.song_id FROM song_tags st JOIN tags t ON st.tag_id = t.id AND t.name = 'ENERGETIC') 

如果你的SQL服務器支持INTERSECT命令,你可以這樣做:

SELECT songs.* FROM songs 
    WHERE songs.song_id IN 
    (SELECT song_tags.song_id FROM song_tags st JOIN tags t ON st.tag_id = t.id AND t.name = 'VOCAL' 
    INTERSECT 
    SELECT song_tags.song_id FROM song_tags st JOIN tags t ON st.tag_id = t.id AND t.name = 'ENERGETIC') 

這我認爲這是一個更酷的方式來做到這一點。

希望有所幫助。:)

+0

感謝您的回答,但archana的答案更有效率:) 乾杯! – Leoss

+0

嗯......我想也是......但據我瞭解,IN並不是一個完整的匹配查詢 - 我認爲它會匹配*標籤中的任意一個*,這意味着您將得到一張歌曲列表那就是聲樂**或**充滿活力,但不一定都是。 –

+0

最後'總共= 2'聲明使其成爲AND聲明,再次思考。 – Leoss

相關問題