代码之家  ›  专栏  ›  技术社区  ›  Jason Christa

选择项/属性列表中具有多个属性的项的SQL语句是什么?

  •  5
  • Jason Christa  · 技术社区  · 15 年前

    假设我有一个表,其中列出了项和属性,

    frog    green
    cat     furry
    frog    nice
    cat     4 legs
    frog    4 legs
    

    从items列中,我要选择同时具有green和4 legs属性的唯一对象。在这种情况下,我希望能回到青蛙的身上。最有效的查询是什么?

    9 回复  |  直到 13 年前
        1
  •  9
  •   van    15 年前
    select  item.name 
    from    item 
    where   item.attribute in ('4 legs', 'green') 
    group by item.name 
    having  count(distinct item.attribute) = 2
    
        2
  •  2
  •   Bill Karwin    15 年前

    最有效的方法是使用自连接:

    SELECT * FROM attributes a1 
    JOIN attributes a2 USING (item_name) -- e.g. frog
    WHERE a1.value = 'green' AND a2.value = '4 legs';
    

    有些人使用的另一种解决方案是“分组依据”技巧:

    SELECT item_name FROM attributes
    WHERE value IN ('4 legs', 'green')
    GROUP BY item_name
    HAVING COUNT(*) = 2;
    

    但是,根据您使用的RDBMS品牌,GroupBy解决方案可能不如Join高效。还有一种方法可以随着表中的卷的增长而更好地扩展。

        3
  •  1
  •   Otávio Décio    15 年前

    从表中选择*,其中thing='frog'

    没有什么比清楚地知道你想要什么更好的了。

        4
  •  1
  •   Jerod Venema    15 年前
    select
        item, count(*)
    from
        @temp
    where
        attribute in ('4 legs','green')
    group by
        item
    having
        count(*) = 2 -- this "2" needs to be replaced with however many attributes you have
    
        5
  •  1
  •   Scott Ivey    15 年前

    您还可以分别查询每个属性,然后与它们相交…

    /*
    -- create sample table...
    create table #temp1
        (item varchar(max),
        attrib varchar(max))
    
    -- populate sample table (SQL 08)...
    insert #temp1
    values ('frog', 'green'), ('cat', 'furry'), ('frog', 'nice'), ('cat', '4 legs'), ('frog', '4 legs')
    */
    
    
    SELECT  item
    FROM    #temp1
    WHERE   attrib = 'green'
    INTERSECT
    SELECT  item
    FROM    #temp1
    WHERE   attrib = '4 legs'
    
        6
  •  0
  •   Christopher Klein    15 年前

    创建两个表,一个是项,另一个是属性。
    项可以是name、intattributeid,其中intattributeid是对attributes表的外键引用。这样,您就可以根据所关心的内容来执行select语句。

        7
  •  0
  •   eKek0    15 年前

    但也许这能帮助你:

    SELECT * 
    FROM tbl t1
    INNER JOIN tbl t2 ON t1.Name = t2.Name
    WHERE t1.Attribute = 'green' AND t2.Attribute = '4 legs'
    
        8
  •  0
  •   gbn    15 年前

    很难,因为它不是一个标准化的模型。 这是个周末。

    您正在跨多个未连接的行进行筛选,因此必须依次提取每个属性,然后匹配项。

    SELECT
       item
    FROM
        (SELECT
            item
        FROM
            Mytable
        WHERE
            attribute = '4 legs') k1
        JOIN
        (SELECT
            item
        FROM
            Mytable
        WHERE
            attribute = 'green') k2 ON k1.item = k2.item
    
        9
  •  0
  •   HLGEM    15 年前

    如果可能的话,我会重新设计。这不是您能够同时有效查询12个值的功能(它需要12个联接)

    请阅读这篇维基百科文章 http://en.wikipedia.org/wiki/Entity-Attribute-Value_model#Downsides

    从未见过使用此模型的数据库最终没有遇到严重的性能问题。对于非数据库人员来说,这种设计看起来很优雅,但实际上是数据库设计不当的标志。

    推荐文章