查询匹配多行?

时间:2013-05-23 14:24:02

标签: sql postgresql

我们的系统中有下一个表格

对象

object_id    object_description
    1             "Car"
    2             "Person"

属性

attribute_id    attribute_name
     1             "hair_color"
     2             "height"
     3             "number_of_doors"
     4             "engine_size"

attribute_value

attribute_id    attribute_value_id    value
    1                1                "black"
    1                2                "blonde"
    2                1                "more than 1 meter"
    2                2                "less than 1 meter"
    3                1                "5 doors"
    3                2                "3 doors"
    4                1                "more than 1.9"
    4                2                "less than 1.9"

object_attribute

object_id    attribute_id    attribute_value_id
    1            3                1 -- Car, number of doors,5
    1            3                2 -- Car, number of doors,2
    1            4                1 -- Car, engine size, greater than 1.9
    1            4                2 -- Car, engine size, less than 1.9

通过这种结构,我们在获得符合多个标准的物体时遇到了很多问题(即所有车辆都有3个门,发动机尺寸大于1.9) 目前我们正在使用INTERSECTS来做这个

SELECT OBJECT_ID
  FROM object_attribute
 WHERE  attribute_id       = 3
   AND attribute_value     = 2 
INTERSECT 
SELECT OBJECT_ID
  FROM object_attribute
 WHERE  attribute_id       = 4
   AND attribute_value     = 1

有不同的对象具有不同数量的属性,因此我们不能再使用固定数量的JOIN或INTERSECT了

有没有办法以“动态方式”生成所有属性的多个组合?

我们希望实现的是一个动态查询,它构建一个这样的视图:

  

object_id | att_name_1 | att_value_1 | att_name_2 | att_value2 | att_name_n | attr_value_n

由于属性的数量是可变的,我们应该在插入新对象时对查询进行三角处理和更新

伙计我认为我的想法是不可能的,所以我们可能会在运行时使用这种动态查询构造。谢谢大家的答案

1 个答案:

答案 0 :(得分:1)

经过一些测试后,我提出了以下问题:

select distinct 
a.attribute_name, o.object_description, av.value,
oa.attribute_id, oa.object_id, oa.attribute_value_id
from object_attribute oa
inner join attribute a on (oa.attribute_id = a.attribute_id and a.attribute_id = 3)
inner join object o on (oa.object_id = o.object_id and o.object_id = 1)
inner join attribute_value av on (oa.attribute_value_id = av.attribute_value_id and av.attribute_value_id = 2)
where 
(av.attribute_id = 3 and o.object_id = 1 and av.attribute_value_id = 2)

union
select distinct 
a.attribute_name, o.object_description, av.value,
oa.attribute_id, oa.object_id, oa.attribute_value_id
from object_attribute oa
inner join attribute a on (oa.attribute_id = a.attribute_id and a.attribute_id = 4)
inner join object o on (oa.object_id = o.object_id and o.object_id = 1)
inner join attribute_value av on (oa.attribute_value_id = av.attribute_value_id and     av.attribute_value_id = 1)
where 
(av.attribute_id = 4 and o.object_id = 1 and av.attribute_value_id = 1)

导致以下结果: query results

如果您使用的是MS SQL Server,我会将其放在一个存储过程中,该过程接受三个Id作为参数。