首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >多对多关系SQL查询

多对多关系SQL查询
EN

Stack Overflow用户
提问于 2012-06-06 19:28:17
回答 5查看 3.1K关注 0票数 3

我正在尝试创建一个可以在多对多关系数据库中获取结果的查询。

到目前为止,我得到了以下信息:

具有歌曲的一个表、具有标签的一个表以及作为一首歌曲的一个‘链接’表可以具有多个标签,并且一个标签可以属于多首歌曲。

它看起来是这样的:

代码语言:javascript
运行
复制
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命令,但我没有成功地创建查询。

如有任何帮助,我们不胜感激!

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-06-06 19:41:27

这将获得所有的歌曲,匹配任何标签的,首先返回那些匹配它们的歌曲:

代码语言:javascript
运行
复制
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

这将只返回那些与所有标签的匹配的歌曲:

代码语言:javascript
运行
复制
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)。

票数 3
EN

Stack Overflow用户

发布于 2012-06-06 19:33:31

下面是基本多对多select语句。

代码语言:javascript
运行
复制
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子句是基于标记的时,将其反转过来

代码语言:javascript
运行
复制
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子句:

代码语言:javascript
运行
复制
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')

返回带有特定标签的特定歌曲,例如,如果您想按名称和标签进行搜索

代码语言:javascript
运行
复制
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')

您还可以过滤连接表本身,这有时是必要的:

代码语言:javascript
运行
复制
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%'

查找不带标签的歌曲

代码语言:javascript
运行
复制
select s.*
from songs s
left join songs_tags st on s.songId = st.songId
where st.songId is null

要查找具有所有标签的歌曲:

代码语言:javascript
运行
复制
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
票数 5
EN

Stack Overflow用户

发布于 2012-06-06 19:32:38

代码语言:javascript
运行
复制
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的所有歌曲

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10913308

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档