MySQL获取具有多个筛选值的产品
问题:MySQL获取具有多个筛选值的产品,mysql,Mysql,问题: 我如何获得所有的红色和尺寸S的产品? 这意味着我只得到product2:product(颜色:绿色,红色=>size:S) 说明: 我在从应用了特定过滤器的数据库中选择产品时遇到了问题。下面您将找到我的表,并查看真正的SQL 表产品: id | title ------------------------------ 1 | Product (color:green => size:S) 2 | Product (color:green,red => size:S) 3
我如何获得所有的
红色
和尺寸S
的产品?
这意味着我只得到product2:product(颜色:绿色,红色=>size:S)
说明:我在从应用了特定过滤器的数据库中选择产品时遇到了问题。下面您将找到我的表,并查看真正的SQL 表
产品:
id | title
------------------------------
1 | Product (color:green => size:S)
2 | Product (color:green,red => size:S)
3 | Product (color:red)
表过滤器
id | name
------------
1 | Color
2 | Size
表filter\u值
id | filter_id | name
---------------------
1 | 1 | green
2 | 1 | red
3 | 2 | S
id | product_id | filter_id | filter_value_id
---------------------------------------------
1 | 1 | 1 | 1
2 | 1 | 2 | 3
3 | 2 | 1 | 1
4 | 2 | 1 | 2
5 | 2 | 2 | 3
6 | 3 | 1 | 2
表产品过滤器值
id | filter_id | name
---------------------
1 | 1 | green
2 | 1 | red
3 | 2 | S
id | product_id | filter_id | filter_value_id
---------------------------------------------
1 | 1 | 1 | 1
2 | 1 | 2 | 3
3 | 2 | 1 | 1
4 | 2 | 1 | 2
5 | 2 | 2 | 3
6 | 3 | 1 | 2
要选择过滤器值为红色的所有产品,我运行以下查询:
# ALL COLOR RED
SELECT p.*
FROM product p
LEFT JOIN product_filter_value pfv ON p.id = pfv.product_id
WHERE (pfv.filter_id IN ('1'))
AND (pfv.filter_value_id IN ('2'))
GROUP BY p.id
LIMIT 10 OFFSET 0;
# ALL SIZE S
SELECT p.*
FROM product p
LEFT JOIN product_filter_value pfv ON p.id = pfv.product_id
WHERE (pfv.filter_id IN ('2'))
AND (pfv.filter_value_id IN ('3'))
GROUP BY p.id
LIMIT 10 OFFSET 0;
要选择过滤器值为S
的所有产品,我运行以下查询:
# ALL COLOR RED
SELECT p.*
FROM product p
LEFT JOIN product_filter_value pfv ON p.id = pfv.product_id
WHERE (pfv.filter_id IN ('1'))
AND (pfv.filter_value_id IN ('2'))
GROUP BY p.id
LIMIT 10 OFFSET 0;
# ALL SIZE S
SELECT p.*
FROM product p
LEFT JOIN product_filter_value pfv ON p.id = pfv.product_id
WHERE (pfv.filter_id IN ('2'))
AND (pfv.filter_value_id IN ('3'))
GROUP BY p.id
LIMIT 10 OFFSET 0;
但是,我如何获得所有的红色
和尺寸S
的产品呢?
这意味着我只能得到product2:product(颜色:绿色,红色=>size:S)
我无法让sql小提琴工作,但我想我还是要试一试。对于不同的筛选器类型,可能必须有不同的联接。表别名为pfv1的联接用于筛选器1,pfv2用于筛选器2
SELECT *
FROM product p
LEFT JOIN product_filter_value pfv1 ON p.id = pfv1.product_id and pfv1.filter_id = 1
LEFT JOIN product_filter_value pfv2 ON p.id = pfv2.product_id and pfv2.filter_id = 2
WHERE (pfv1.filter_id IN ('1'))
AND (pfv1.filter_value_id IN ('2'))
and (pfv2.filter_id IN ('2'))
AND (pfv2.filter_value_id IN ('3'))
GROUP BY p.id
LIMIT 10 OFFSET 0;
在没有where
子句的情况下查看整个集合可能会很有趣:
SELECT *
FROM product p
LEFT JOIN product_filter_value pfv1 ON p.id = pfv1.product_id and pfv1.filter_id = 1
LEFT JOIN product_filter_value pfv2 ON p.id = pfv2.product_id and pfv2.filter_id = 2
+ ------- + ----------------------------------- + ------- + --------------- + -------------- + -------------------- + ------- + --------------- + -------------- + -------------------- +
| id | title | id | product_id | filter_id | filter_value_id | id | product_id | filter_id | filter_value_id |
| 1 | Product (color:green => size:S) | 1 | 1 | 1 | 1 | 2 | 1 | 2 | 3 |
| 2 | Product (color:green,red => size:S) | 3 | 2 | 1 | 1 | 5 | 2 | 2 | 3 |
| 2 | Product (color:green,red => size:S) | 4 | 2 | 1 | 2 | 5 | 2 | 2 | 3 |
| 3 | Product (color:red) | 6 | 3 | 1 | 2 | | | | |
+ ------- + ----------------------------------- + ------- + --------------- + -------------- + -------------------- + ------- + --------------- + -------------- + -------------------- +
4 rows
产品2有两条记录,因为它有两种颜色,而产品3没有大小属性,所以最后四列没有值。您可以分别获取这两个元素,将它们合并,然后过滤它们(以易于阅读的word格式)
给定(顺便说一下,您的sql FIDLE不会加载)
子查询s获取颜色,子查询t获取大小
select u.stitle product
from
(
select s.* , t.* from
(
select p.id sid,p.title stitle,fv.name sfvname,f.name sname
from product p
join product_filter_value pfv on pfv.product_id = p.id
join filter_value fv on fv.id = pfv.filter_value_id
join filter f on f.id = fv.filter_id
where f.name = 'color'
) s
join
(
select p.id tid,p.title ttitle,fv.name tfvname,f.name tfname
from product p
join product_filter_value pfv on pfv.product_id = p.id
join filter_value fv on fv.id = pfv.filter_value_id
join filter f on f.id = fv.filter_id
where f.name = 'size'
) t on s.stitle = t.ttitle
) u
where u.sname = 'color' and u.sfvname = 'red' and u.tfname = 'Size' and u.tfvname = 'S'
让我们从寻找一件事的简单基础开始。
它可以是一个大小,颜色或任何其他你的真实数据。
问题可能是
SELECT
pfv.product_id,
f.name
from
product_filter_value pfv
join filter_value fv
ON pfv.filter_value_id = fv.id
AND fv.name = "what you are looking for"
JOIN filter f
ON pfv.filter_id = f.id
现在,您可以对同一查询中加入的每个唯一项执行多个操作。
我将为每个被筛选的唯一对象添加别名表的后缀。
如果适用,您甚至可以通过附加子查询联接(如ProdBrand alias)添加品牌
SELECT
p.product_id,
p.title,
ProdColor.name as Color,
ProdSize.name as Size
from
Product p
JOIN ( select
pfv.Product_id,
fv.name
from
product_filter_value pfv
JOIN filter_value fv
ON pfv.filter_value_id = fv.id
AND fv.name = "red"
JOIN filter f
ON pfv.filter_id = f.id
AND f.name = "Color" ) ProdColor
ON P.id = ProdColor.Product_ID
JOIN ( select
pfv.Product_id,
fv.name
from
product_filter_value pfv
JOIN filter_value fv
ON pfv.filter_value_id = fv.id
AND fv.name = "S"
JOIN filter f
ON pfv.filter_id = f.id
AND f.name = "Size" ) ProdSize
ON P.id = ProdSize.Product_ID
现在,如果你想尝试多种颜色或尺寸,
只需将每个子查询的条件更改为
AND INLIST( fv.name, "red", "blue" ) -- example for red OR blue
AND INLIST( fv.name, "S", "M" ) -- example for Small OR Medium
这可能是一个很长的查询,但是单独查看每一部分是非常简单的。它的目的是一个标准的颜色,大小,品牌等,你只是加入到你的整体条件的一部分,以获得产品
我可以在SQLFiddle上找到您原始模式中的SQLFiddle,它确实起了作用,但现在对我来说它也坏了。我总是对SQLfiddle有问题。SQLfiddle确实坏了,似乎不是一个很好的服务。您的第一个示例似乎运行良好。我不确定你的第二个。我仍然需要涉及filter\u value\u id。第二个示例仅用于深入了解没有filter时会发生什么。很高兴第一个适合你。我还没有测试过你。CGritton的答案似乎简单得多。我对性能没有把握。另一方面,查询使用的是过滤器名称,而不是id。