我是一个很好的人,我有两个表:“产品”和“产品属性”。
这是一些虚构的数据(实际的东西涉及更多的表格)
产品表:
product_id | product_name
10 | aaa
11 | bbb
12 | ccc
产品属性表:
attribute_id | product_id
21 | 10
23 | 10
24 | 10
21 | 11
24 | 11
21 | 12
25 | 12
每个产品都有多个可能的属性。我有一个属性ID列表,如(21,10,25)
,我需要选择其属性是该列表子集的所有产品。
是否可以在一个查询中执行此操作?
当我过滤(21,24)时,所需的输出仅返回产品11(bbb)
当我过滤(21,23,24)时,所需的输出是返回产品10和11.
当我过滤(21)时,所需的输出将返回none(因为所有产品至少有一个其他属性)。
答案 0 :(得分:5)
如果您假装过滤器在表格中:
select *
from product p
where not exists (
select 1
from attributes a
where a.product_id = p.product_id
and not exists(
select 1
from filter f
where f.id_attribute = a.id_attribute))
如果它在构造的查询中:
select *
from product p
where not exists (
select 1
from attributes a
where a.product_id = p.product_id
and attribute_id not in (<list>))
这不是我的头脑,所以可能有拼写错误。
答案 1 :(得分:1)
假设您的产品表名为Product,该表中的ID列名为Id:
SELECT * from Product p where p.Id IN
(Select id_product from ProductAttributes where id_attribute in (21, 23, 24))
答案 2 :(得分:1)
select
P.id,
P.name,
count(P.id) as matched_attr_count,
count(PA.a_id) as total_attr_count
from
product_attributes PA
left join product P on P.id = PA.p_id and PA.a_id in (21,23,24)
group by
PA.p_id
having
matched_attr_count = total_attr_count;
答案 3 :(得分:1)
这应该只返回那些id,其中每个id的所有属性都完全包含在列表中:
select attribute_match.id_product from
(select id_product, count(*) c from attributes
where id_attribute in (21, 10, 25)
group by id_product) attribute_match,
(select id_product, count(*) c_count from attributes
group by id_product) attribute_total
where attribute_match.id_product = attribute_total.id_product
and attribute_match.c = attribute_total.c
答案 4 :(得分:1)
在MySQL支持EXCEPT
查询组合之前,
SELECT product_id
FROM attributes
WHERE product_id NOT IN (
SELECT product_id
FROM attributes
WHERE attribute_id NOT IN (21, 23, 24)
)
GROUP BY product_id
UNION
SELECT id
FROM products AS p
LEFT JOIN attributes AS a
ON p.id = a.product_id
WHERE a.product_id IS NULL
如果您希望只拥有具有所有给定属性的产品,请在第一个外部查询中添加HAVING COUNT(*)=n
子句,其中“n”是属性列表的长度。
答案 5 :(得分:0)
基于你的洞察力,我进一步优化了它,并且只使用了1 COUNT语句:
SELECT * ,COUNT(p.product_id) AS c FROM product_attribute pa
LEFT JOIN products p ON pa.product_id = p.product_id AND pa.attribute_id NOT IN ($filter_list)
GROUP BY pa.product_id
HAVING c=0
有用吗? :)
编辑:
该代码不会返回产品的名称或其他可能包含的字段。这是正确的:
SELECT * ,COUNT(pa.product_id ) AS c FROM products p
LEFT JOIN product_attribute pa ON pa.product_id = p.product_id AND pa.attribute_id NOT IN ($filter)
GROUP BY p.product_id
HAVING c=0
答案 6 :(得分:-1)
让我发布简单的虚数据(实际的东西涉及更多的表)
表产品
product_id | product_name
10 | aaa
11 | bbb
表 product_attribute
attribute_id | product_id <br>
21 | 10
23 | 10
24 | 10
21 | 11
24 | 11
我想要那个:
(21,24)
仅返回产品11(bbb)(21,23,24)
以返回两个产品时(21)
时只返回无(因为没有产品只有该属性)