MySQL查询以搜索带有特定标记的项目

MySQL查询以搜索带有特定标记的项目,mysql,sql,select,Mysql,Sql,Select,我有一个MySQL数据库,包含以下表格: items | id, item items_tags | id, item_name, item_id, tag_name, tag_id tags | id, tag 我想允许用户搜索带有任何标签或标签组合的项目。下面是一些示例数据来说明我想做什么: items: id | item ----------- 1 | banana 2 | orange 3 | tomato items_tags: id | item

我有一个MySQL数据库,包含以下表格:

items      | id, item
items_tags | id, item_name, item_id, tag_name, tag_id
tags       | id, tag
我想允许用户搜索带有任何标签或标签组合的项目。下面是一些示例数据来说明我想做什么:

items:

id | item
-----------
1  | banana
2  | orange
3  | tomato

items_tags:

id | item_name | item_id | tag_name | tag_id
---------------------------------------------
1  | banana    | 1       | yellow   | 1
2  | banana    | 1       | fruit    | 2
3  | orange    | 2       | orange   | 3
4  | orange    | 2       | fruit    | 2
5  | tomato    | 3       | red      | 4
6  | tomato    | 3       | vegetable| 5    

tags:

id | tag
--------------
1  | yellow
2  | fruit
3  | orange
4  | red
5  | vegetable
我可以运行什么查询来只返回标记为黄色和水果的项目,即应该返回项目的第1行

谢谢

更新: 以下是可行的答案:

SELECT * 
  FROM items 
 WHERE id IN (
              SELECT item_id
                FROM items_tags
               WHERE tag_name IN ('yellow', 'fruit')
            GROUP BY item_id
              HAVING COUNT(*) = 2
             )
谢谢车坛的帮助

试试这个:

    Select *, count(1) as noOfTags from 
    items_tags
 group by item_id 
having  tag_name in ('yellow','fruit') and  noOfTags=2

如果您希望项目带有两个标签中的任何一个,则:

select distinct item_id, item_name 
from items_tags 
where tag_name in ('yellow', 'fruit'); 
select item_id, item_name 
from items_tags 
where tag_name in ('yellow', 'fruit')
group by item_id, item_name
having count(*) = 2; 
如果您希望项目同时具有两个标记,则:

select distinct item_id, item_name 
from items_tags 
where tag_name in ('yellow', 'fruit'); 
select item_id, item_name 
from items_tags 
where tag_name in ('yellow', 'fruit')
group by item_id, item_name
having count(*) = 2; 
根据你的评论

  select a.id, a.item 
    from items a, items_tags b, tags c 
   where a.id = b.item_id
     and b.tag_id = c.id
group by id, item
  having (group_concat(c.tag) like '%yellow%' 
         and  group_concat(c.tag) like '%fruit%')
      or group_concat(c.tag) = 'red';
此查询提供items表中的id和item。它给出的商品既有黄色标签,也有水果标签。和只有红色标签的项目

若您想要获得具有两个标记且只有两个标记的项,那个么在having子句中使用以下条件

(group_concat(c.tag) like '%yellow%' 
and group_concat(c.tag) like '%fruit%'
and count(*) = 2) 
    
yes noofTags在此确保项目已标记所有标记,yes如果要搜索更多标记,则将其添加到括号之间 关于马克的评论,还有一点我同意,那就是它们是无用的&如果你想得到这样的东西,你可以使用view,至少可以节省一些空间。
注意:我还不能发表评论,所以我发布了类似“回答对不起”的帖子。

item\u name和tag\u name在items\u标记上都是多余的-item\u id和tag\u id本身就足以链接回父表上的名称。是的,我知道这一点。我在items_tags表中有item_name和tag_name,这样在开发过程中,当我在PHPMyAdmin这样的管理程序中查看原始数据时,可以更容易地筛选原始数据。我计划在生产前删除它们。知道如何从结果中排除某些标记吗?我尝试添加一个AND NOT IN子句,但没有成功..谢谢更新的工作答案。帮助我在我的项目中正确使用Laravel分组标签。谢谢!这让我非常接近。如何让MySQL从表项返回匹配项的行,而不是从items\u标记返回匹配项的行?此外,如果我想搜索两个以上的标签,我显然会添加另一个标签或tag_name='tag',但我是否只是将noOfTags=增加到我要搜索的标签数量?这将返回带有黄色或水果标签或两者标签的项目。我希望它只返回带有这两个标签的项目。此外,它还返回item_id和item_名称。我希望它从items表中返回id和item这显然很简单,但在我的实际数据库中,items表包含的信息比其他表中不包含的name和id多得多。谢谢谢谢,更新正是我想要的。只需要做一个小的调整,它就返回了我想要的结果:select*from items where id in select item_id from items_tags where tag_name in'yellow','fruit'group by item_id具有count*=2;参见第三个查询。你可以进一步调整。