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')