我有以下表格:
Widgets表是一个简单的产品/列表表,其中包含id,user_id,添加/更新等。
Fields表列出了小部件的字段名称。可以有任何数量的字段(例如,高度,宽度,价格,年份,颜色等)。字段表:
每个小部件都可以包含任意数量的字段和值。 Widgets_Fields表将如下所示:
如果您只是想获取一个小部件或一组小部件的所有字段,那么它非常简单:
select widget_id from widgets_fields where widget_id = xxx
但是,如果您正在搜索小部件并且只想找到那些对其字段具有特定值的小部件,该怎么办?也可行
select widget_id from widgets_fields where field_id = xxx and value = xxx
当我想根据多个字段选择小部件时,我的问题就出现了。例如,所有小部件都是“红色”或“橙色”且年份为2012年或2011年
select widget_id from widgets_fields where
(field_id = xxx and (value = 'red' or value = 'orange')
and
(field_id = xxy and (value = 2012 or value = 2011)
这会产生一个不可能的地方。或者我可以做这样的事情
select widget_id from widgets_fields where
field_id in (xxx, xxy)
and value in ('red', 'orange', 2012, 2011)
但它不一定会返回我想要的内容,因为它将在任何提供的字段ID中查找给定值。
所以,最后,我的问题是,是否有任何方法可以正确构建查询来实现此目的?我肯定一定有,但我已经研究了一段时间,还没有找到解决方案。
答案 0 :(得分:1)
all widgets that are either 'red' or 'orange'
AND also have a year of 2012 or 2011
可以通过subquerying和INNER一起加入结果来完成
SELECT widget_id FROM
(SELECT widget_id FROM widgets_fields
WHERE field_id = 'color' and value in ('red', 'orange')) ResultSetA
INNER JOIN
(SELECT widget_id FROM widgets_fields
WHERE field_id = 'year' and value in (2011, 2012)) ResultSetB
ON ResultSetA.widget_id = ResultSetB.widget_id
简单来说,这将是“获取所有红色和橙色小部件的ID,然后从2011年或2012年获取所有小部件的ID,然后给我两个列表中出现的ID。
答案 1 :(得分:1)
立即想到两种方法。一种是使用EXSISTS
子查询:
select * from widgets where
exists (select * from widgets_fields where field_id = xxx and (value = 'red' or value = 'orange') and widget_id=widgets.id)
and exists (select * from widgets_fields where field_id = xxy and (value = 2012 or value = 2011) and widget_id=widgets.id)
另一种方法是使用带有子查询的JOIN
:
select a.widget_id from
(select widget_id from widgets_fields where field_id = xxx and (value = 'red' or value = 'orange')) a
join (select widget_id from widgets_fields where field_id = xxy and (value = 2012 or value = 2011)) b
on (a.widget_id=b.widget_id)
我不确定性能,可能取决于你拥有多少数据以及有哪些索引。