【问题标题】:sql query for multi valued attributessql查询多值属性
【发布时间】:2015-01-19 16:48:25
【问题描述】:

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

所以,假设表格如下:

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

并且我想要位置为 US 且所有者为 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';

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

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    假设每个 GUID 没有 duplicate 属性,您可以在没有 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

    【讨论】:

      【解决方案2】:

      一般来说,这里的 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)
        ...
      

      【讨论】:

      • 谢谢,数据已经在表中。我无法控制它的存储方式。
      【解决方案3】:

      将你的目标插入一个临时表,然后加入它。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-07-06
        • 2012-02-10
        • 2012-10-06
        • 1970-01-01
        • 2012-04-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多