带有MySQL的高级网上商店过滤功能

时间:2018-12-26 10:05:49

标签: php mysql mysqli database-management

我正在使用数据库设计similar to this在MySQL和PHP中创建一个网上商店(参见图片)
我对具有不同规格的多价商品没有问题,就像上面链接的问题一样。

这将是一间计算机网上商店,因此不需要我为每种产品制定规格。我可以对它们进行分类,例如。智能手机,笔记本电脑...并为每个类别添加规格。
智能手机可能具有:品牌,处理器类型,屏幕尺寸,颜色,电池,价格等。
笔记本电脑:处理器,图形卡,品牌,价格,大小,...

我还认为不需要[combinations]表,因为我认为不必要地存储了很多东西。

我的问题是过滤产品。我可以轻松地选择所有这些,或者仅选择一个,例如。选择所有白色手机或所有白色或金色手机,但是我无法选择所有带有8MP前置摄像头的白色手机。

表结构:
[products]:id,名称,category_id,描述

[categories]:ID,名称

[specifications]:id,category_id,名称

[spec_values]:id,product_id,spec_id,值

以下SQL返回所有具有金色或具有8mp前置摄像头的独特产品。

SELECT products.id, products.name, spec_values.value AS Filter
FROM products, categories, specifications, `spec_values` 
WHERE products.category_id = categories.id 
    AND spec_values.product_id = products.id 
    AND ((specifications.name = 'Color' AND spec_values.value = 'Gold') 
        OR (specifications.name = 'Front Camera' AND spec_values.value = '8MP')) 
GROUP BY products.id;

我希望在它们之间有一个逻辑AND而不是OR,但是仅仅更改它不会返回任何内容,因为它不能在一行中完成,因为我的规范名称和值存储在多行中

一种解决方案是对每个过滤器使用SQL CREATE TEMPORARY TABLE,但是我认为这将需要大量不必要的服务器端工作。

另一种方法是获取所有非唯一值,并使用PHP遍历它们,然后检查它们是否都存在;如果是,则将它们显示在页面上,但那仍然可能是一团糟。

由于我对SQL的经验不足,是否有更好的解决方案我没有注意到? 预先感谢您的任何帮助。祝你有美好的一天!

1 个答案:

答案 0 :(得分:0)

您可以为此使用聚合。包括一个HAVING子句以检查计数是否与过滤器数匹配。除非两次或多次插入准确的规格值,否则您将知道满足该条件的产品必须过滤所有规格值。如果没有,则缺少一行(或多行),即一(或多行)规格值。

SELECT products.id,
       products.name
       FROM products
            INNER JOIN spec_values
                       ON spec_values.product_id = products.id 
            INNER JOIN specifications
                       ON specifications.id = spec_values.spec_id
       WHERE specifications.name = 'Color' AND spec_values.value = 'Gold'
              OR specifications.name = 'Front Camera' AND spec_values.value = '8MP'
       GROUP BY products.id,
                products.name
       HAVING count(*) = 2;

顺便说一句,建议在FROM子句中的逗号分隔列表上使用显式联接语法,以提高可读性。