提取与多个属性过滤器匹配的产品(实体属性值)

时间:2018-10-19 05:54:01

标签: php mysql join filter entity-attribute-value

我试图增加从具有基本实体-属性-值模型的数据库中获取产品时添加多个过滤器的可能性。过滤器基于属性值,例如:

  • 颜色:绿色,红色
  • 尺寸:小,大

单个过滤器没有问题,但是我不知道如何一次处理多个过滤器。


示例数据 :(精简版)

SQL file with this example structure & data

产品

id name
1  jacket
2  shirt

product_variants

id product_id
1  1
2  2
3  2

属性

id name
1  colors
2  sizes

attribute_value

id attribute_id value
1  1            green
2  1            red
3  2            small
4  2            large

variant_details

id product_variant_id attribute_value_id
1  1                  3                    (jacket - small)
2  2                  1                    (shirt - green)
3  2                  3                    (shirt - small)
4  3                  1                    (shirt - green)
5  3                  4                    (shirt - large)

在此示例中,三个变体为:

  • 外套(小)
  • 衬衫(绿色和小号)
  • 衬衫(绿色和大号)

目标

我想传递属性值的ID并获取与所有所述属性值匹配的产品,例如:

products.php?attr=1&4

应该获取green(1)和large(4)的产品,例如,只有第三个变体符合条件,因此所需的结果将是:

product_id product_desc
2          shirt

我尝试过的事情

我认为这不会有太大帮助,但是我有一个属性:

products.php?attr=1

应该产生属性值为绿色(1)的任何东西:

SELECT products.id, products.desc, attribute_value.value FROM products
LEFT JOIN product_variants ON products.id = product_variants.product_id
LEFT JOIN variant_details ON variant_details.product_variant_id = product_variants.id
LEFT JOIN attribute_value ON attribute_value.id = variant_details.attribute_value_id
WHERE attribute_value.id = 1
GROUP BY products.id

此问题是在 WHERE 子句之前,它产生的是

id name    value
1  jacket  small
2  shirt   green
2  shirt   small
2  shirt   green
2  shirt   large

,例如,我不知道如何过滤具有绿色和大值列的行。我认为我用于查询的方法是错误的。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

通过以下查询,我能够使其以某种方式工作

SELECT products.id, products.desc FROM products
WHERE EXISTS 
(
SELECT * FROM product_variants
LEFT JOIN variant_details ON variant_details.product_variant_id = product_variants.id
LEFT JOIN attribute_value ON attribute_value.id = variant_details.attribute_value_id
WHERE product_variants.product_id = products.id AND attribute_value.id = 1
)
AND EXISTS
(
SELECT * FROM product_variants
LEFT JOIN variant_details ON variant_details.product_variant_id = product_variants.id
LEFT JOIN attribute_value ON attribute_value.id = variant_details.attribute_value_id
WHERE product_variants.product_id = products.id AND attribute_value.id = 4
)

我之所以说 ,是因为它会返回具有一个或多个变体的每个请求属性的所有产品。

示例

以一件产品为例,它有两种颜色和两种尺寸的衬衫,其变化形式可能是:

  • 衬衫(绿色和小号)
  • 衬衫(绿色和大号)
  • 衬衫(红色和小号)

请注意,没有红色和较大的变体。如果我对红色和大号进行上述查询,它仍将与该产品匹配,因为其变体之一为“红色”,另一个为“大”。

我决定将其添加为答案而不是进行编辑,因为它实现了将产品与两个(或多个)属性进行匹配的目标,但我仍然希望看到一个答案,其结果被限制为仅匹配一个产品的变体,或实现此目的的另一种方法。