[英]Mysql JOIN for items and tags
Consider three tables: one of items, one of tags on those items, and the third which maps tag ids to tag names. 考虑三个表:一个是项目,一个是这些项目上的标签,第三个是将标签ID映射到标签名称。
Items: 项目:
ITEM ID ITEM NAME
-------------------
1 Item 1
2 Item 2
3 Item 3
Tags: 标签:
ID TAG ID ITEM ID
1 1 1
2 2 1
3 3 1
4 1 2
5 1 3
Tag Names: 标签名称:
TAG ID TAG NAME
1 TAG_A
2 TAG B
3 TAG C
So only item 1 has tags TAG_A, TAG_B and TAG_C. 因此,只有第1项具有标签TAG_A,TAG_B和TAG_C。
How do you do a select that retrieves all items which have TAG_A, TAG_B and TAG_C without doing 3 INNER JOINs? 你怎么做一个选择,检索所有有TAG_A,TAG_B和TAG_C的项目而不做3个内部联接? In other words, I know I can do a select and say 换句话说,我知道我可以做一个选择并说出来
INNER JOIN item_tags pt4 ON pt4.item_id = p.item_id AND pt4.tag_id = 1
INNER JOIN item_tags pt13 ON pt13.item_id = p.item_id AND pt13.tag_id = 2
INNER JOIN item_tags pt19 ON pt19.item_id = p.item_id AND pt19.tag_id = 3
but that's got to be inefficient, right? 但那效率低下,对吧?
What about a subquery, like 那个子查询怎么样呢
SELECT * FROM items WHERE ... AND item_id IN (SELECT item_id FROM item_tags
WHERE tag_id IN ( 1, 2, 3 )) SELECT * FROM items WHERE ... AND item_id IN(SELECT item_id FROM item_tags
WHERE tag_id IN(1,2,3))
(This exact query wouldn't work - it's an OR on tags, but this is what I'm going for. ) (这个确切的查询不起作用 - 它是标签上的OR,但这就是我想要的。)
Try this query - 试试这个查询 -
SELECT t.item_id FROM tags t
JOIN tag_names tn
ON t.tag_id = tn.tag_id
GROUP BY
t.item_id
HAVING
COUNT(DISTINCT t.tag_id) = (SELECT COUNT(*) FROM tag_names)
The first query (aliased sqlvars) creates a single @NumTags variable of how many tags are in the tag name table so it doesn't need to do it on every qualifying tags group by. 第一个查询(别名sqlvars)创建一个@NumTags变量,表示标记名称表中有多少个标记,因此不需要在每个限定标记组中执行此操作。
The second query (aliased HasAllTags) gets items, grouped by itemid having the total count equal to that of the @NumTags. 第二个查询(别名HasAllTags)获取项目,按itemid分组,总计数等于@NumTags的总计数。
Finally, the HasAllTags is joined to items to pull the data. 最后,HasAllTags与项目连接以提取数据。
select
I.*
from
( select @NumTags := (select count(*) from TagName )) sqlvars,
( select t.ItemID
from Tags t
group by t.ItemID
having count(*) = @NumTags ) HasAllTags
JOIN Items I
on HasAllTags.ItemID = I.ItemID
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.