【发布时间】:2018-10-19 05:54:01
【问题描述】:
在从具有基本实体属性值模型的数据库中获取产品时,我正在尝试添加添加多个过滤器的可能性。过滤器基于以下属性值:
- 颜色:绿色、红色
- 尺寸:小号、大号
我对单个过滤器没有任何问题,但我不知道如何同时处理多个过滤器。
示例数据:(精简版)
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
表属性值:
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
应获取绿色 (1) 和大 (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
例如,我不知道如何过滤那些值列既绿色又大的行。我认为我对查询采取的方法是错误的。
任何帮助将不胜感激。
【问题讨论】:
-
SQL 的输入到底是什么? PS 有一个明显的观点是从 EAV 表中重构一个简单的非 EAV 表。 (EAV 表是一些简单表的元数据表。)然后对这些视图有一个明显的查询来给出你想要的。找到那些查询。 PS 如果适合您的目的,首选的 SQL 演示站点是 sqlfiddle.com。
-
请use text, not images/links, for text (including code, tables & ERDs)。使用链接/图像仅是为了方便补充文本和/或无法在文本中给出的内容。永远不要给出没有图例/键的图表。如果您有代表,请使用编辑功能内联,而不是链接 - 使您的帖子独立。
-
了解 LEFT JOIN 返回的内容:INNER JOIN 行加上由 NULL 扩展的不匹配的左表行。作为 LEFT JOIN 的一部分,始终知道您想要什么 INNER JOIN。在 LEFT JOIN ON 删除任何由 NULL 扩展的行之后,需要右表列不为 NULL 的 WHERE 或 ON,即只留下 INNER JOIN 行,即“将 LEFT JOIN 转换为 INNER JOIN”。你有那个。
-
感谢所有 cmets philipxy。 1.- 查找将 EAV 表转换为简单明了的查询:好主意!我会调查的。 2.- 文本不是链接:知道了。我决定链接 sql,因为它似乎太多了,并且这里已经描述了表,但会考虑在内。 3.- JOIN 类型:将进一步研究,再次感谢!
-
您希望此查询的视图和/或结果可能是 EAV。也许就像“产品 P 变体 V 具有属性 A 值 X”。但是您还没有阐明输入过滤器数据是如何进入 SQL 的。而且还不清楚它的“匹配”是什么。通过由列名参数化的语句模板来表征表(基本或查询结果)——它的 (特征)谓词——在表中生成真实语句的行。 PS 子行值出现在一个表中,所有子行值出现在另一个表中的表是Codd原来relational-division的结果。
标签: php mysql join filter entity-attribute-value