Mysql 如何获得n个选择的交点?
我有三个表:数据、标签和数据标签 数据Mysql 如何获得n个选择的交点?,mysql,mariadb,Mysql,Mariadb,我有三个表:数据、标签和数据标签 数据 id data ------------------------------------ 1 A string of long data A. 2 A string of long data B. 3 A string of long data C. 4 A string of long data D. 5 A string of long data E. 6 A string of lo
id data
------------------------------------
1 A string of long data A.
2 A string of long data B.
3 A string of long data C.
4 A string of long data D.
5 A string of long data E.
6 A string of long data F.
7 A string of long data G.
标签
id tag
------------
1 gold
2 silver
3 copper
数据标签相关信息
data tag
------------------
1 1
1 2
2 1
3 2
4 3
5 1
5 2
5 3
6 1
7 1
如您所见,有数据和标记,还有一个关系表来确定哪些标记被分配给哪些数据。这里的数据是关于金属的。在本例中:
金色标记已分配给5个数据字符串。
银色标签已分配给3个数据字符串。
铜标记已分配给2个数据字符串
我想查询数据库并获得金、银和铜标签的交叉点。这意味着我希望获得分配给所有3个标记的表_数据。结果将是数据表中的1行,行id为5:“一个长数据字符串E。”
什么查询可以完成这个交叉点
到目前为止,我只能通过查询1个标记来实现查询:
SELECT data.id, data.data
FROM data
INNER JOIN data_tag_rel ON data.id = data_tag_rel.data
INNER JOIN tags ON data_tag_rel.tag = tags.id
WHERE tags.tag = "gold"
非常感谢 聚合提供了一个选项:
SELECT d.id, d.data
FROM data d
INNER JOIN data_tag_rel dtr ON d.id = dtr.data
INNER JOIN tags t ON dtr.tag = t.id
WHERE t.tag IN ('gold', 'silver', 'copper')
GROUP BY d.id, d.data
HAVING COUNT(DISTINCT t.tag) = 3;
速度将根据您的数据而变化。Tim的答案可能足够快,以达到实际目的,但如果您发现答案不够快,您可以通过在需要之前不加入数据来稍微改进答案(此处的其他更改只是风格上的,不太可能产生任何效果): 如果您有大量数据,则对每个标记进行单独连接可能会更快,尤其是如果您知道哪些标记是稀有的,并且可以从最稀有到最不稀有:
select d.id, d.data
from data_tag_rel dtr1 on dtr
join data_tag_rel dtr2 on dtr2.data=dtr1.data and dtr2.tag=(select id from tag where tag='silver')
join data_tag_rel dtr3 on dtr3.data=dtr2.data and dtr3.tag=(select id from tag where tag='copper')
join data d on d.id=dtr3.data
where dtr1.tag=(select id from tag where tag='gold')
(两个问题都未经测试)谢谢!它起作用了!我看到你修复了WHERE-after-GROUP的小错误。非常感谢。这是速度方面最有效的方法吗?你知道我可以测试的其他方法吗?
select d.id, d.data
from data_tag_rel dtr1 on dtr
join data_tag_rel dtr2 on dtr2.data=dtr1.data and dtr2.tag=(select id from tag where tag='silver')
join data_tag_rel dtr3 on dtr3.data=dtr2.data and dtr3.tag=(select id from tag where tag='copper')
join data d on d.id=dtr3.data
where dtr1.tag=(select id from tag where tag='gold')