带 MySQL 的高级网店过滤
Advanced webshop filtering w/ MySQL
我正在 MySQL 和 PHP 中使用数据库设计 similar to this(见图)
制作网上商店
我对具有不同规格的多价商品没有问题,就像上面链接的问题一样。
这将是一个电脑网上商店,所以我没有必要为每个产品制定规格。我可以对它们进行分类,例如。智能手机、笔记本电脑...并为每个类别添加规格。
智能手机可能有:品牌、处理器类型、屏幕尺寸、颜色、电池、价格等
笔记本电脑:处理器、显卡、品牌、价格、尺寸……
我也觉得没必要 [combinations]
table,因为在我看来,不必要地存储太多了。
我的问题是过滤产品。我可以轻松 select 所有这些,或者只是一个,或者例如。 select 所有白色手机或所有白色或金色手机,但我不能 select 所有具有 8MP 前置摄像头的白色手机。
Table 结构:
[products]
: id, name, category_id, 描述
[categories]
: id, name
[specifications]
: id, category_id, 名字
[spec_values]
:id,product_id,spec_id,值
以下SQL returns所有不同的金色或具有 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
但只是简单地更改它 returns 什么都没有,因为它不能在一行中实现,因为我的规范名称和值存储在多行中。
一个解决方案是 SQL CREATE TEMPORARY TABLE
每个过滤器,但我认为这需要大量不必要的服务器端工作。
另一种方法是获取所有非不同值并使用 PHP 遍历它们并检查它们是否都存在;如果是,则将它们显示在页面上,但是,那个也可能很乱。
是否有更好的解决方案,由于我对 SQL 缺乏经验而没有注意到?
预先感谢您的任何帮助。祝你有美好的一天!
您可以为此使用聚合。包括一个 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
子句中对逗号分隔列表使用显式连接语法。
我正在 MySQL 和 PHP 中使用数据库设计 similar to this(见图)
制作网上商店
我对具有不同规格的多价商品没有问题,就像上面链接的问题一样。
这将是一个电脑网上商店,所以我没有必要为每个产品制定规格。我可以对它们进行分类,例如。智能手机、笔记本电脑...并为每个类别添加规格。
智能手机可能有:品牌、处理器类型、屏幕尺寸、颜色、电池、价格等
笔记本电脑:处理器、显卡、品牌、价格、尺寸……
我也觉得没必要 [combinations]
table,因为在我看来,不必要地存储太多了。
我的问题是过滤产品。我可以轻松 select 所有这些,或者只是一个,或者例如。 select 所有白色手机或所有白色或金色手机,但我不能 select 所有具有 8MP 前置摄像头的白色手机。
Table 结构:
[products]
: id, name, category_id, 描述
[categories]
: id, name
[specifications]
: id, category_id, 名字
[spec_values]
:id,product_id,spec_id,值
以下SQL returns所有不同的金色或具有 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
但只是简单地更改它 returns 什么都没有,因为它不能在一行中实现,因为我的规范名称和值存储在多行中。
一个解决方案是 SQL CREATE TEMPORARY TABLE
每个过滤器,但我认为这需要大量不必要的服务器端工作。
另一种方法是获取所有非不同值并使用 PHP 遍历它们并检查它们是否都存在;如果是,则将它们显示在页面上,但是,那个也可能很乱。
是否有更好的解决方案,由于我对 SQL 缺乏经验而没有注意到? 预先感谢您的任何帮助。祝你有美好的一天!
您可以为此使用聚合。包括一个 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
子句中对逗号分隔列表使用显式连接语法。