简体   繁体   English

MySQL Select - 连接匹配所有表的表

[英]MySQL Select - join tables that match all

I have a database with 3 tables - products, tags, & product_tags. 我有一个包含3个表的数据库 - 产品,标签和product_tags。 I need a query that will return all of the products that have all of the specified tags. 我需要一个查询,它将返回所有具有所有指定标签的产品。 In other words, don't return the product if it does not have all of the specified tags. 换句话说,如果产品没有所有指定的标签,请不要退货。

products
+----+-----+--------+------------------------+
| id | uid | name   | description            |
+----+-----+--------+------------------------+
| 1  | p1  | ball   | something that bounces |
+----+-----+--------+------------------------+
| 2  | p2  | block  | for building stuff     |
+----+-----+--------+------------------------+
| 3  | p3  | bucket | holds stuff            |
+----+-----+--------+------------------------+
| 4  | p4  | shovel | scoops stuff           |
+----+-----+--------+------------------------+


tags
+----+-----+--------+
| id | uid | name   |
+----+-----+--------+
| 1  | t1  | blue   |
+----+-----+--------+
| 2  | t2  | red    |
+----+-----+--------+
| 3  | t3  | green  |
+----+-----+--------+
| 4  | t4  | yellow |
+----+-----+--------+
| 5  | t5  | orange |
+----+-----+--------+


product_tags
+-------------+---------+
| product_uid | tag_uid |
+-------------+---------+
| p1          | t1      |
+-------------+---------+
| p1          | t2      |
+-------------+---------+
| p2          | t3      |
+-------------+---------+
| p2          | t4      |
+-------------+---------+
| p2          | t5      |
+-------------+---------+
| p3          | t1      |
+-------------+---------+
| p4          | t1      |
+-------------+---------+
| p4          | t5      |
+-------------+---------+

Here are some examples of results I'm looking for: 以下是我正在寻找的一些结果示例:

Select the products that are red (t2): 选择红色的产品(t2):

+-------------+------+
| product_uid | name |
+-------------+------+
| p1          | ball |
+-------------+------+

Select all products that are red & blue (t2, t1): 选择所有红色和蓝色的产品(t2,t1):

+-------------+------+
| product_uid | name |
+-------------+------+
| p1          | ball |
+-------------+------+

Select all products that are red, blue & yellow (t2, t1, t4): 选择所有红色,蓝色和黄色的产品(t2,t1,t4):

+--------------------+
|     NO PRODUCTS    |
+--------------------+

Select all products that are blue (t1): 选择所有蓝色产品(t1):

+-------------+--------+
| product_uid | name   |
+-------------+--------+
| p1          | ball   |
+-------------+--------+
| p3          | bucket |
+-------------+--------+
| p4          | shovel |
+-------------+--------+

Select all products that are blue & orange (t1, t5): 选择所有蓝色和橙色的产品(t1,t5):

+-------------+--------+
| product_uid | name   |
+-------------+--------+
| p4          | shovel |
+-------------+--------+

Here is a link to a SQLFiddle that's already set up. 这是一个已经设置的SQLFiddle的链接。 I tried a LEFT JOIN but it doesn't get me what I'm looking for. 我尝试了LEFT JOIN,但它并没有让我得到我正在寻找的东西。

http://sqlfiddle.com/#!9/795615/6 http://sqlfiddle.com/#!9/795615/6

EDIT: Updated with @spencer7593's suggestion 编辑:更新了@ spencer7593的建议

Assuming your tags are unique, you can use count to filter only by products that have a number of hits equal to the passed tags. 假设您的标记是唯一的,您可以使用count仅过滤具有等于传递标记的匹配数的产品。

This approach has the advantage of allowing for unlimited tags as an input. 该方法具有允许无限标签作为输入的优点。

SELECT products.uid
FROM product_tags
JOIN products ON product_tags.product_uid = products.uid
WHERE product_tags.tag_uid IN ('t2', 't1')
GROUP BY products.uid
HAVING COUNT(DISTINCT product_tags.tag_uid) = 2

Or for 3 tags: 或3个标签:

SELECT products.uid
FROM product_tags
JOIN products ON product_tags.product_uid = products.uid
WHERE product_tags.tag_uid IN ('t3', 't2', 't1')
GROUP BY products.uid
HAVING COUNT(DISTINCT product_tags.tag_uid) = 3

and so on... 等等...

try this: 试试这个:

select product_id,tag_uuid,uid,d.name,description,color from
(

select product_id,tag_uuid,b.name as color from
(select product_id,tag_uuid from product_tags) as a
LEFT JOIN
(select uid,name from tags) as b
on a.tag_uuid = b.uid

) as c
left JOIN
(select id,uid,name,description from products) as d
on c.product_id = d.uid


where color = 'blue'

just change the where if you need another color. 如果你需要另一种颜色,只需改变它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM