每个产品的产品过滤方案我有以下四个表。 每个产品都可以有多个属性,可以有多个值。
如何为多个属性搜索的用户请求构建SQL查询,如
CPU: >1000
Price <700
我的最后一个Jquery因为性能而腐败:
SELECT
attributes_vals.*, handys.*
FROM
handys join handy_has_vals on handys.id=handy_has_vals.handy_id
join attributes_vals on attributes_vals.id=handy_has_vals.val_id
WHERE
`attributes_vals`.`attr_id`=374
AND(`attributes_vals`.`vals` >=1000 AND `attributes_vals`.`vals` >=1500)
OR `attributes_vals`.`attr_id`=68 AND(`attributes_vals`.`vals`='YES')
OR `attributes_vals`.`attr_id`=11 AND( `attributes_vals`.`vals` LIKE 'GPRS%')
小提琴&amp;测试:http://SQLFiddle.com/#!2/bba51/2
这是表格
handys
id | name | modell
1 | Samsung | galaxy A
2 | Samsung | galaxy B
3 | Samsung | galaxy C
4 | Samsung | galaxy D
handy_has_vals
handy_id | attr_id | val_id
1 | 1 | 1
1 | 2 | 3
1 | 3 | 6
1 | 4 | 11
2 | 1 | 2
2 | 2 | 4
2 | 3 | 7
2 | 4 | 10
3 | 1 | 1
3 | 2 | 5
3 | 3 | 8
3 | 4 | 10
4 | 1 | 2
4 | 2 | 3
4 | 3 | 9
4 | 4 | 11
attributes_vals
id | attr_id | vals
1 | 1 | 'YES'
2 | 1 | 'No'
3 | 2 | '1200'
4 | 2 | '1000'
5 | 2 | '1500'
6 | 3 | '300'
7 | 3 | '350'
8 | 3 | '800'
9 | 3 | '550'
10 | 4 | 'YES'
11 | 4 | 'No'
attributes
id | attr_name
1 | 'GPS'
2 | 'CPU'
3 | 'Price'
4 | 'WLAN'
答案 0 :(得分:1)
它应该类似于:
SELECT * FROM handys h
INNER JOIN handy_has_vals hv ON h.id = hv.handy_id
INNER JOIN attributes a ON hv.attr_id = a.id
INNER JOIN attributes_vals av ON av.attr_id = a.id
WHERE ( a.attr_name = 'CPU' AND av.vals > '1000' ) or ( a.attr_name = 'Price' AND av.vals < '700' )
并且,为了按数字进行比较,而不是字符串:
SELECT * FROM handys h
INNER JOIN handy_has_vals hv ON h.id = hv.handy_id
INNER JOIN attributes a ON hv.attr_id = a.id
INNER JOIN attributes_vals av ON av.attr_id = a.id
WHERE ( a.attr_name = 'CPU' AND cast(av.vals AS UNSIGNED) > '1000' ) or ( a.attr_name = 'Price' AND cast(av.vals AS UNSIGNED) < '700' )
尽管在where子句中使用CAST
可以保证全表扫描,如果你有足够的记录,这将大大降低性能。
答案 1 :(得分:0)
尝试此查询
SELECT
attributes_vals . *, handys . *
from
handys
join
handy_has_vals ON handys.id = handy_has_vals.handy_id
join
attributes_vals ON attributes_vals.id = handy_has_vals.val_id
WHERE
attributes_vals.attr_id IN (68, 11, 374)
AND ((attributes_vals.vals >= 1000 AND attributes_vals.vals >= 1500)
OR attributes_vals.vals = 'YES' OR attributes_vals.vals LIKE 'GPRS%')
答案 2 :(得分:0)
试试这个
SELECT
attributes_vals . *, handys . *
from
handys
join
handy_has_vals ON handys.id = handy_has_vals.handy_id
join
attributes_vals ON attributes_vals.id = handy_has_vals.val_id
WHERE
((attributes_vals.vals >= 1000 AND attributes_vals.vals >= 1500)
OR attributes_vals.vals = 'YES' OR attributes_vals.vals LIKE 'GPRS%')