问题:
我如何获得Red
和尺寸S
的所有产品?
这意味着我只获得产品2: Product (color:green,red => size:S)
说明
我从使用某些过滤器的数据库中选择产品时遇到了问题。您可以在下面找到我的表格,并查看SQLfiddle的真实SQL。
表product
:
id | title
------------------------------
1 | Product (color:green => size:S)
2 | Product (color:green,red => size:S)
3 | Product (color:red)
表filter
id | name
------------
1 | Color
2 | Size
表filter_value
id | filter_id | name
---------------------
1 | 1 | green
2 | 1 | red
3 | 2 | S
表product_filter_value
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
要选择具有过滤器值red
的所有产品,请运行此查询:
# 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;
要选择具有过滤器值S
的所有产品,请运行此查询:
# 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;
但我如何获得Red
和尺寸S
的所有产品?
这意味着我只获得产品2: Product (color:green,red => size:S)
答案 0 :(得分:1)
我无法让sql小提琴工作,但我还是认为我还是试一试。您可能必须为不同的筛选器类型具有不同的连接。表别名pfv1的连接用于filter1,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没有最后四列的值,因为它没有大小属性。
答案 1 :(得分:0)
您可以单独获取2个元素,加入它们然后过滤它们(以易于阅读的单词格式)
给出(并且你的sql小提琴不会加载)/*
drop table if exists product;
create table product(id int ,title varchar(50));
insert into product values
( 1 , 'Product (color:green => size:S)' ),
( 2 , 'Product (color:green,red => size:S)' ),
( 3 , 'Product (color:red)' );
drop table if exists filter;
create Table filter(id int, name varchar(5));
insert into filter values
( 1 , 'Color'),
( 2 , 'Size');
drop table if exists filter_value;
create table filter_value( id int, filter_id int, name varchar(5));
insert into filter_value values
( 1 , 1 , 'green'),
( 2 , 1 , 'red'),
( 3 , 2 , 'S');
drop table if exists product_filter_value;
create Table product_filter_value(id int, product_id int, filter_id int, filter_value_id int);
insert into product_filter_value values
( 1 , 1 , 1 , 1),
( 2 , 1 , 2 , 3),
( 3 , 2 , 1 , 1),
( 4 , 2 , 1 , 2),
( 5 , 2 , 2 , 3),
( 6 , 3 , 1 , 2);
*/
子查询获取颜色,子查询获取大小
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'
答案 2 :(得分:0)
让我们从寻找一件事的简单基础开始。 它可以是大小,颜色或您的真实数据所具有的任何其他内容。 查询可以是
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别名
)添加品牌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