我正在尝试创建一个可以在多对多关系数据库中获取结果的查询
到目前为止,我得到以下内容:
一张带有歌曲的表格,一张带有标签的表格和一张“链接”表作为一首歌曲可以有多个标签,一个标签可以属于多首歌曲。
它看起来像这样:
Songs Link Tags
======= ===== =========
Sid Sid Tid
Songname Tid Tagname
现在假设您有3首歌曲A B和C以及3个标签:X,Y和Z. 歌曲A具有标签Y,歌曲B具有标签Z,歌曲C具有标签X和Z。
我设法创建了一个只通过一个标签来获取歌曲的查询(例如Z给出了B和C)
但是,如何在输入多个标签时创建搜索歌曲的查询(例如,键入(搜索)字段)。
我已经搜索了几次命令INTERSECT和INNER JOIN,但我还没能成功创建一个查询。
感谢任何帮助!
答案 0 :(得分:4)
这是您的基本多对多选择语句。
select s.*, t.*
from songs s
join songs_tags st on s.songId = st.songId
join tags t on t.tagId = st.tagId
-- optional where clause
where s.name = 'my song'
当where子句基于标记时,将其翻转
select s.*, t.*
from tags t
join songs_tags st on s.songId = st.songId
join songs s on s.songId = st.songId
-- optional where clause
where t.name = 'whatever'
如果您想要返回包含多个标签的所有歌曲,只需更改where子句:
select s.*
from tags t
join songs_tags st on s.songId = st.songId
join songs s on s.songId = st.songId
where t.name in ('tag1', 'tag2', 'tag3')
返回包含特定标签的特定歌曲,例如,如果您想按名称和标签搜索
select s.*, t.*
from songs s
join songs_tags st on s.songId = st.songId
join tags t on t.tagId = st.tagId
where s.name like '%mysong%' and t.name in ('tag1', 'tag2')
您也可以自己过滤联接表,有时是必要的:
select s.*, t.*
from songs s
join songs_tags st on s.songId = st.songId
join tags t on t.tagId = st.tagId and t.name in ('tag1', 'tag2')
where s.name like '%mysong%'
查找没有标签的歌曲
select s.*
from songs s
left join songs_tags st on s.songId = st.songId
where st.songId is null
查找包含所有标签的歌曲:
select s.*
from songs s
join songs_tags st1 on s.songid = st1.songid
join songs_tags st2 on s.songid = st2.songid
join songs_tags st3 on s.songid = st3.songid
where st1.tagid = 1 and st2.tagid = 2 and st3.tagid = 3
答案 1 :(得分:3)
这首歌将获得与任何标签匹配的所有歌曲,并返回首先匹配所有歌曲的歌曲:
SELECT s.Sid, s.Songname
FROM Songs s
JOIN Link l ON ( l.Sid = s.Sid )
JOIN Tags t ON ( t.Tid = s.Tid )
WHERE t.Tagname IN ( 'X', 'Y' )
GROUP BY s.Sid, s.Songname
ORDER BY COUNT(1) DESC
此歌曲只返回符合所有标签的歌曲:
SELECT s.Sid, s.Songname
FROM Songs s
JOIN Link l ON ( l.Sid = s.Sid )
JOIN Tags t ON ( t.Tid = s.Tid )
WHERE t.Tagname IN ( 'X', 'Y' )
GROUP BY s.Sid, s.Songname
HAVING COUNT(1) = 2 -- 'X' and 'Y'
如果您生成此查询,则还必须生成计数(在我的情况下为2
)。
答案 2 :(得分:2)
SELECT DISTINCT s.Sid, s.Songname
FROM
Songs s join Link l on s.Sid=l.Sid
join Tags t on t.Tid=l.Tid
WHERE t.Tagname in ('Z', 'Y');
这将返回所有标记为Z或Y
的歌曲答案 3 :(得分:1)
select distinct songs.*
from songs
inner join link on link.sid = songs.sid
inner join tags on tags.tid = link.tid
where tagname IN ('a','b','c')
这样的事情?
答案 4 :(得分:0)
你可以尝试这个 -
select a.Sid, a.SongName, c.Tid, c.TagName
from Songs a
LEFT OUTER JOIN Links b ON a.Sid = b.Sid
LEFT OUTER JOIN Tags c ON b.Tid = c.Tid
WHERE c.TagName IN ('Tag1', 'Tag2', ...... ) // as many tags you want
group by a.Sid, a.SongName, c.Tid, c.TagName