sql查询多值属性

时间:2015-01-19 16:48:26

标签: sql oracle

我有每个由guid表示的资源,它们具有属性名称 - 值对。我想查询 对于具有给定属性名称值对的资源。

所以,假设表格如下:

GUID                                      ATTR_SUBTYPE        ATTR_VAL 
63707829116544a38c5a508fcde031a4            location            US 
63707829116544a38c5a508fcde031a4            owner               himanshu       
44d5bf579d9f4b9a8c41429d08fc51de            password            welcome1 
44d5bf579d9f4b9a8c41429d08fc51de            host                retailHost       
c67d8f5d1a9b41428f029d55b79263e1            key                 random 
c67d8f5d1a9b41428f029d55b79263e1            role                admin 

我希望所有资源都位于美国,所有者都是olaf。

一个可能的查询是:

select guid from table where attr_subtype = 'location' and attr_value = ‘US' INTERSECT select guid from table where attr_subtype = 'owner' and attr_value = ‘himanshu';

查询中可以有任意数量的属性名称值对,因此每对附加一个交集 在查询中。我想知道我们是否可以构建更好的查询,因为交叉点很昂贵。

3 个答案:

答案 0 :(得分:2)

假设每个GUID没有重复的属性,您可以在没有JOIN的情况下获得所需的结果:

SELECT "GUID" FROM T
WHERE ( "ATTR_SUBTYPE" = 'location' AND "ATTR_VAL" = 'US' )
OR    ( "ATTR_SUBTYPE" = 'owner' AND "ATTR_VAL" = 'himanshu' )
GROUP BY "GUID"
HAVING COUNT(*) = 2 -- <-- keep only GUID have *both* attributes

请参阅http://sqlfiddle.com/#!4/80900/2

答案 1 :(得分:1)

将目标插入临时表,然后加入它。

select t.guid 
from table as t 
join temp
on t.attr_subtype = temp.attr_subtype
and t.attr_value = temp.attr_value 

答案 2 :(得分:1)

一般来说,JOIN会比INTERSECT好。它提供了在几次全表扫描完成之前获得第一个记录的机会。但无论如何你选择了一个缓慢的数据结构,所以如果它减速就不会很好。

尝试类似

的内容
select * 
from 
  (select * from table where attr_subtype = 'location' and attr_value = 'US') t1 
    join
  (select * from table where attr_subtype = 'owner' and attr_value = 'himanshu') t2
    on (t1.guid = t2.guid)
  ...