按多个属性选择产品,使用AND代替OR连接器,数据模型EAV

时间:2015-11-29 20:27:22

标签: php mysql e-commerce entity-attribute-value

我对电子商务网站产品过滤器的查询存在问题。

我有这样的EAV数据模型:

products          [id, title....]
attributes        [id, name]
attributes_entity [product_id, attribute_id, value_id]
attributes_values [id, value]

我的查询:

SELECT 
products.id, 
products.title 
FROM 
products 
WHERE products.id IN 
(
SELECT attributes_entity.product_id FROM attributes_entity INNER JOIN 
attributes ON attributes_entity.attribute_id=attributes.id INNER JOIN 
attributes_values ON attributes_entity.value_id=attributes_values.id 
WHERE 
(
(attributes.name="Memory" AND attributes_values.value="16GB") 
>> AND
(attributes.name="Color" AND attributes_values.value="Gold")
)
) 
AND products.category_id = :category_id

问题是当我使用>> AND(attributes.name =" Memory" AND attributes_values.value =" 16GB")子查询我得到0结果但是当我使用OR时它给了我更多的结果需要与这两个条件无关。

例如,当我收到请求时:"内存= 16GB,颜色=黑色"。我希望得到iPhone 5 16BG Black,而不是所有(金色,太空灰等)iPhone 16GB

我正在寻找查询示例,最好是描述它是如何工作的。

此致 安东

1 个答案:

答案 0 :(得分:2)

你的子查询应该是这样的:

SELECT
  attributes_entity.product_id
FROM
  attributes_entity INNER JOIN attributes
  ON attributes_entity.attribute_id=attributes.id
  INNER JOIN attributes_values ON
  attributes_entity.value_id=attributes_values.id 
WHERE 
  (attributes.name="Memory" AND attributes_values.value="16GB") 
  OR
  (attributes.name="Color" AND attributes_values.value="Gold")
GROUP BY
  attributes_entity.product_id
HAVING
  COUNT(DISTINCT attributes.name)=2

此解决方案使用GROUP BY子查询。您必须使用OR,因为该属性在同一行上不能同时是Memory和Color,它们都可以是true但在不同的行上。 COUNT(DISTINCT attributes.name)计算Color或Memory的数字属性,如果它是2那么第一个条件为真的至少有一行,而另一个条件为真的则为1行。