3

我正在尝试创建一个可以在多对多关系数据库中获取结果的查询。
到目前为止,我得到了以下内容:
一张带有歌曲的表格,一张带有标签的表格和一个“链接”表格,因为一首歌曲可以有多个标签,一个标签可以属于多首歌曲。

它看起来像这样:

Songs       Link        Tags
=======     =====       =========
Sid          Sid        Tid
Songname     Tid        Tagname

现在假设您有 3 首歌曲 AB 和 C 以及 3 个标签:X、Y 和 Z。
歌曲 A 有标签 Y,歌曲 B 有标签 Z,歌曲 C 有标签 X 和 Z。

我设法创建了一个查询,以仅通过一个标签获取一首歌曲(例如 Z 给出 B 和 C)。
但是,当输入多个标签(例如,输入(搜索)字段)时,我如何创建一个搜索歌曲的查询。

我已经搜索过几次命令 INTERSECT 和 INNER JOIN 出现了,但我无法成功创建查询。

任何帮助表示赞赏!

4

5 回答 5

5

这是您的基本多对多选择语句。

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
于 2012-06-06T11:33:31.380 回答
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在我的情况下)。

于 2012-06-06T11:41:26.657 回答
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 的歌曲

于 2012-06-06T11:32:38.327 回答
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')

像这样的东西?

于 2012-06-06T11:33:07.690 回答
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 
于 2012-06-06T11:46:06.043 回答