查询匹配多行?

Ait*_*tor 5 sql postgresql

我们的系统中有下表

对象

object_id    object_description
    1             "Car"
    2             "Person"
Run Code Online (Sandbox Code Playgroud)

属性

attribute_id    attribute_name
     1             "hair_color"
     2             "height"
     3             "number_of_doors"
     4             "engine_size"
Run Code Online (Sandbox Code Playgroud)

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"
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

有了这个结构,我们在获得符合多个标准的物体时会遇到很多问题(即所有车辆都有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
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

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

Rub*_*ren 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)
Run Code Online (Sandbox Code Playgroud)

结果如下: 查询结果

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