5

我们的系统中有下一张桌子

对象

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_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

由于属性的数量是可变的,我们应该在插入新对象时触发和更新查询

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

4

1 回答 1

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)

结果如下: 查询结果

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

于 2013-05-24T14:32:48.230 回答