代码之家  ›  专栏  ›  技术社区  ›  Samuel Danielson

SQL分组是否存在设计缺陷?

sql
  •  30
  • Samuel Danielson  · 技术社区  · 15 年前

    为什么SQL要求我指定要分组的属性?为什么不能全部使用非聚合?

    如果属性未聚合且不在 小组通过 子句,那么不确定的选择将是唯一的选项,假设元组是无序的(MySQL是这样做的),这是一个巨大的gotcha。据我所知,PostgreSQL要求所有属性不出现在 小组通过 必须聚合,这加强了它的多余性。

    • 我是否遗漏了一些东西,或者这是一个语言设计缺陷,它促进了松散的实现并使查询更难编写?
    • 如果我遗漏了一些东西,那么什么是无法推断组属性的示例查询?_
    9 回复  |  直到 10 年前
        1
  •  11
  •   Dour High Arch    14 年前

    SQL:select priority,count(*) from rule_class
    group by priority
    
    

    PRIORITY COUNT(*) 70 1 50 4 30 1 90 2 10 4

    SQL:select decode(priority,50,'Norm','Odd'),count(*) from rule_class group by priority

    DECO COUNT(*) Odd 1 Norm 4 Odd 1 Odd 2 Odd 4

    SQL:select decode(priority,50,'Norm','Odd'),count(*) from rule_class group by decode(priority,50,'Norm','Odd')

    DECO COUNT(*) Norm 4 Odd 8

        2
  •  6
  •   ypercubeᵀᴹ    14 年前

    friend car

    SELECT f.id
         , f.firstname
         , f.lastname
         , f.birthdate
         , COUNT(NOT c.sold AND NOT c.crashed) AS owned
         , COUNT(c.sold) AS sold
         , COUNT(c.crashed) AS crashed
         , COUNT(c.friendid) AS totalcars
    FROM friend f
    LEFT JOIN car c     <--to catch (shame!) those friends who have never had a car 
      ON f.id = c.friendid
    GROUP BY f.id
           , f.firstname
           , f.lastname
           , f.birthdate
    ORDER BY f.birthdate DESC
    

    GROUP BY id firstname, lastname and birthdate f.id

    SELECT f.id
         , f.firstname
         , f.lastname
         , f.birthdate
         , COUNT(NOT c.sold AND NOT c.crashed) AS owned
         , COUNT(c.sold) AS sold
         , COUNT(c.crashed) AS crashed
         , COUNT(c.friendid) AS totalcars
    FROM friend f
    LEFT JOIN car c     <--to catch (shame!) those friends who have never had a car 
      ON f.id = c.friendid
    GROUP BY f.id
    ORDER BY f.birthdate 
    

    SELECT ORDER BY

    Debunking group by myths

        3
  •  3
  •   Antony Koch    15 年前

    select  id, count(a), b, c, d
    from    table
    group by
            id, b, c, d
    

    select  id, myCount, b, c, d
    from    table t
            inner join (
                select id, count(*) as myCount
                from table
                group by id
            ) as myCountTable on myCountTable.id = t.id
    

        4
  •  3
  •   cindi    15 年前

    create table people
    (  Nam char(10)
      ,Adr char(10)
    )
    
    insert into people values ('Peter', 'Tibet')
    insert into people values ('Peter', 'OZ')
    insert into people values ('Peter', 'OZ')
    
    insert into people values ('Joe', 'NY')
    insert into people values ('Joe', 'Texas')
    insert into people values ('Joe', 'France')
    
    -- Give me people where there is a duplicate address record
    
    select * from people where nam in 
    (
    select nam              
    from People        
    group by nam, adr        -- group list different from select list
    having count(*) > 1
    )
    
        5
  •  2
  •   adopilot    15 年前

    SQL MGM Studio将为您添加代码。

    我认为这种方法对于插入语句非常有用。当我需要编写在表中插入大量字段的脚本时,我只需要从表中选择要插入的*并在更改要插入的select语句类型之后,

        6
  •  2
  •   Community CDub    8 年前

    我同意

    我完全同意这个问题。我问的是同一个 here .

    我真的认为这是语言缺陷。

    我知道有人反对这一点,但我还没有使用一个group by子句,它包含现实世界中select子句中所有非聚合字段以外的任何内容。

        7
  •  1
  •   Mutation Person    15 年前
        8
  •  1
  •   Chris Latta    15 年前

    我想说,更可能是语言设计的选择,决策是明确的,而不是含蓄的。例如,如果我希望将数据分组的顺序与输出列的顺序不同,该怎么办?或者,如果要按未包含在所选列中的列分组?或者,如果只输出分组列而不使用聚合函数?只有在group by子句中明确地声明我的偏好,我的意图才是明确的。

    您还必须记住,SQL是一种非常古老的语言(1970年)。看看Linq是如何翻转所有东西以使IntelliSense工作的——我们现在很明显,但是SQL早于IDES,所以不可能考虑到这些问题。

        9
  •  0
  •   Rob Bednark Bohdan    10 年前

    “超级”属性影响结果的顺序。

    考虑:

    create table gb (
      a number,
      b varchar(3),
      c varchar(3)
    );
    
    insert into gb values (   3, 'foo', 'foo');
    insert into gb values (   1, 'foo', 'foo');
    insert into gb values (   0, 'foo', 'foo');
    
    insert into gb values (  20, 'foo', 'bar');
    insert into gb values (  11, 'foo', 'bar');
    insert into gb values (  13, 'foo', 'bar');
    
    insert into gb values ( 170, 'bar', 'foo');
    insert into gb values ( 144, 'bar', 'foo');
    insert into gb values ( 130, 'bar', 'foo');
    
    insert into gb values (2002, 'bar', 'bar');
    insert into gb values (1111, 'bar', 'bar');
    insert into gb values (1331, 'bar', 'bar');
    

    本声明

    select sum(a), b, c
      from gb
    group by b, c;
    

    结果在

        44 foo bar
       444 bar foo
         4 foo foo
      4444 bar bar
    

    而这一个

    select sum(a), b, c
      from gb
    group by c, b;
    

    结果在

       444 bar foo
        44 foo bar
         4 foo foo
      4444 bar bar