我有三个表产品,属性和product_properties。表结构和值的子集如下:
products
---------------------------------------------
| id | name | description | price |
---------------------------------------------
| 1 | Camera | Color Camera | 100 |
| 2 | Lens 1 | Camera Lens 1 | 20 |
| 3 | Lens 2 | Camera Lens 2 | 30 |
---------------------------------------------
properties
------------------------------------------
| id | name | display |
------------------------------------------
| 1 | lens_mount | Lens Mount |
| 2 | image_circle | Image Circle |
| 3 | focal_length | Focal Length |
| 4 | lens_family | Lens Family |
------------------------------------------
product_properties
------------------------------------------------
| id | value | product_id | property_id |
------------------------------------------------
| 1 | F-Mount | 2 | 1 |
| 2 | C-Mount | 3 | 1 |
| 3 | 42.01 mm | 2 | 2 |
| 4 | 13.00 mm | 3 | 2 |
| 5 | 10.00 | 2 | 3 |
| 6 | 12.00 | 3 | 3 |
| 7 | Standard | 1 | 4 |
| 8 | Standard | 2 | 4 |
| 9 | Standard | 3 | 4 |
------------------------------------------------
这是我的输出条件:
找到相机1的所有镜头(通过lens_family匹配相机和镜头,这里是'标准'),其具有lens_mount ='F-Mount'和image_circle> = 40mm并且focal_length> 5
我尝试了以下查询:
SELECT * FROM products
INNER JOIN product_properties ON products.id = product_properties.product_id
INNER JOIN properties ON properties.id = product_properties.property_id
WHERE (product_properties.value = 'Standard')
AND (properties.name = 'lens_mount' AND product_properties.value = 'F-Mount')
AND (properties.name = 'image_circle' AND product_properties.value >= ABS('40 mm'))
AND (properties.name = 'focal_length' AND product_properties.value >= 5)
但是,如果只有一个条件,则此查询仅提供正确的结果。在所有条件下,它都没有给出任何价值。我尝试使用OR代替AND在where条件下,但这也无助于获得正确的输出。
任何人都可以解决这个问题。提前谢谢。
答案 0 :(得分:3)
您希望在having
子句而不是where
子句中执行逻辑:
SELECT products.id
FROM products
INNER JOIN product_properties ON products.id = product_properties.product_id
INNER JOIN properties ON properties.id = product_properties.property_id
group by products.id
having sum(properties.name = 'lens_family' AND product_properties.value = 'Standard') > 0 and
sum(properties.name = 'lens_mount' AND product_properties.value = 'F-Mount') > 0 and
sum(properties.name = 'image_circle' AND product_properties.value >= ABS('40 mm')) > 0 and
sum(properties.name = 'focal_length' AND product_properties.value >= 5) > 0;
您正在寻找单个产品的一组属性。没有一行可以匹配所有条件 - 它们相互冲突。相反,使用group by
子句将给定产品的行组合在一起。然后计算与每个条件匹配的行数。
having
中的每个子句对应where
声明中的一个原始子句,由sum()
括起来。这会计算匹配的行数。条件确保每个属性至少有一行。
答案 1 :(得分:0)
然后你可以使用该视图的两个副本(一个用于相机,一个用于镜头)并将它们连接在一起以获得所需。
SELECT p.id
,p.name
,pp1.value as Lens_Mount
,pp2.value as Image_Circle
,pp3.value as Focal_Length
,pp4.value as Lens_Family
from products p
left outer join
product_properties pp1
on pp1.product_id = p.id
and pp1.property_id = 1 --lens Mount
left outer join
product_properties pp2
on pp2.product_id = p.id
and pp2.property_id = 2 --Image Circle
left outer join
product_properties pp3
on pp3.product_id = p.id
and pp3.property_id = 3 --Focal Length
left outer join
product_properties pp4
on pp4.product_id = p.id
and pp4.property_id = 3 --Lens Family
where p.name like 'Lens%'
答案 2 :(得分:0)
您应该OR每个条件并计算每个product_id满足多少条件。
因此,您GROUP BY product_id
并使用HAVING
子句过滤结果。
SELECT product_properties.product_id, count(*) as conditions_satisfied FROM products
INNER JOIN product_properties ON products.id = product_properties.product_id
INNER JOIN properties ON properties.id = product_properties.property_id
WHERE product_properties.value = 'Standard'
OR properties.name = 'lens_mount' AND product_properties.value = 'F-Mount'
OR properties.name = 'image_circle' AND product_properties.value >= ABS('40 mm')
OR properties.name = 'focal_length' AND product_properties.value >= 5
GROUP BY product_properties.product_id
HAVING COUNT(*) = 4
注意,如果您真的需要进行数字比较,可能很难比较字符串的属性值。