1

我有以下表格:

  • 小部件
  • 字段
  • Widgets_Fields

Widgets 表是一个简单的产品/列表表,带有 id、user_id、add/updated 等。

字段表列出了小部件的字段名称。可以有任意数量的字段(例如,高度、宽度、价格、年份、颜色等)。字段表:

  • ID
  • 姓名

每个小部件可以具有与其关联的任意数量的字段和值。Widgets_Fields 表如下所示:

  • ID
  • field_id
  • 小部件_id
  • 价值

如果您只是想获取一个小部件或一组小部件的所有字段,这非常简单:

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 中查找给定的值。

所以,最后,我的问题是是否有任何方法可以正确构建查询来完成此操作?我确定一定有,但我已经研究了一段时间,还没有提出解决方案。

4

2 回答 2

1
all widgets that are either 'red' or 'orange' 
AND also have a year of 2012 or 2011

可以通过子查询和 INNER JOIN 一起完成结果

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。

于 2012-08-10T14:40:49.093 回答
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)

另一种是将JOINs 与子查询一起使用:

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)

我不确定性能,它可能取决于您拥有多少数据以及有哪些索引。

于 2012-08-10T14:46:11.317 回答