我想检索设置了某些过滤器的项目。例如,红色或蓝色且较小的列表项应仅返回项 apple。((红色(2)或蓝色(4))和小(5))=>苹果
我找到了 2 个解决方案,但在我看来,这两个解决方案都过于复杂。第一个解决方案在我看来更优雅,因为当我想添加另一个过滤器时AND
,它非常简单。而第二种解决方案将需要另一个JOIN
. 我希望我忽略了一些东西,并且有一个比这个更好的解决方案。
这些问题,
- 有更好的解决方案吗?
- 如果没有更好的解决方案 - 哪个更快/推荐?
项目表
| id | itemname |
├────┼──────────┤
| 1 | apple |
| 2 | orange |
| 3 | banana |
| 4 | melon |
过滤表
│ id │ filtername │
├────┼────────────┤
│ 1 │ orange │
│ 2 │ red │
│ 3 │ green │
│ 4 │ blue │
│ 5 │ small │
│ 6 │ medium │
│ 7 │ big │
│ 8 │ yellow │
item_filter
│ item_id │ filter_id │
├─────────┼───────────┤
│ 1 │ 2 │
│ 1 │ 3 │
│ 1 │ 5 │
│ 2 │ 1 │
│ 2 │ 5 │
│ 3 │ 6 │
│ 3 │ 8 │
│ 4 │ 3 │
│ 4 │ 7 │
基于 GROUP_CONCAT 和 FIND_IN_SET 的第一个解决方案
sqlfiddle:http ://sqlfiddle.com/#!9/26f99/1/0
SELECT * FROM item
JOIN (
SELECT item_id, GROUP_CONCAT(filter_id) AS filters
FROM item_filter
GROUP BY item_id
) AS grp ON grp.item_id = item.id
WHERE (FIND_IN_SET(2,filters) OR FIND_IN_SET(4,filters)) AND FIND_IN_SET(5, filters)
仅基于 JOIN 和 where 子句的第二种解决方案
sqlfiddle:http ://sqlfiddle.com/#!9/f0b95/1/0
SELECT itemname FROM item
JOIN item_filter as filter1 on item.id=filter1.item_id
JOIN item_filter as filter2 on item.id=filter2.item_id
WHERE (filter1.filter_id=2 or filter1.filter_id=4) and filter2.filter_id=5