我正在做电子商务,但在按属性进行过滤时遇到了一些麻烦。
我有2个SQL表(实际上,其中3个,对于ManyToMany关系,我们仅将Product.attributes视为一组ID):
Products (id: integer, name: string, attributes: relationship Many To Many to table attributes)
Attributes (id: integer, value: string)
我的目标是获取大量的属性ID,并仅获取具有这些属性或更多属性的产品,例如:
我具有这些属性:
Attribute(id: 1, name: 'Size M')
Attribute(id: 2, name: 'Size L')
Attribute(id: 3, name: 'Size XL')
我有以下产品:
Product(id: 1, name: 'Tee-shirt 1', attributes: [1,2])
Product(id: 2, name: 'Tee-shirt 2', attributes: [1,2,3])
我需要查询属性[1,2],因此,我应该获得两个产品,如果我具有属性[1,2,3],则只有'T恤2'
我尝试了以下查询:
SELECT * FROM Product p
INNER JOIN Attribute a ON a.id IN p.attributes
WHERE a.id = ALL(SELECT * FROM Attribute WHERE id IN [1,2]);
问题在于,如果产品具有确切的属性且仅具有这两个属性1和2,那么它就可以工作,如果至少有更多属性包含请求的属性,我就需要它也可以工作。
我希望这很清楚。预先谢谢你。
答案 0 :(得分:1)
您正在寻找的所有产品的属性都在(1,2)中
因此,假设您在表产品和属性之间有products_attributes多对多关系
id, product_id, attribute_id
您可以使用
SELECT p.*
FROM Product p
INNER JOIN products_attributes pa ON pa_id.product_id = p.id
where pa.attribute_id IN (1,2)
group by p.id
having count(distinct pa.attribute_id ) >= 2
答案 1 :(得分:0)
如果搜索模式为字符串(包含ID升序排列),则为另一种解决方案:
SET @s = '1,2';
SELECT p.id, p.name, p.attributes
FROM Products p
INNER JOIN Attributes a ON FIND_IN_SET(a.id, p.attributes)
WHERE FIND_IN_SET(a.id, @s)
GROUP BY p.id, p.name, p.attributes
HAVING GROUP_CONCAT(a.id ORDER BY a.id) = @s
请参见demo。
结果:
> id | name | attributes
> -: | :---------- | :---------
> 1 | Tee-shirt 1 | 1,2
> 2 | Tee-shirt 2 | 1,2,3