【问题标题】:SQL - group by with two colums agregation problemSQL - 通过两列聚合问题分组
【发布时间】:2011-01-26 09:59:35
【问题描述】:

我今天的问题是我有一个包含这样行的表:

ID NAME NUMBER IDN
1  dsad 500600 12
1  dsad 600700 13
2  kkkk 111222 56
2  kkkk 333232 57

在一个 ID 示例 1 中,我有 2 个相同的名字、2 个不同的号码和不同的 IDN。

我想要的是为每个 ID 提取单行,其中 idn 值较小。 所以我想要这样的东西

1  dsad  500600 12
2  kkkk  111222 56

是否可以编写单个 sql 以获得该结果?我尝试按 ID 和 NAME 对其进行分组,并使用 min(IDN) 但我被数字字段卡住了:) 有什么想法吗?

【问题讨论】:

    标签: c# .net sql oracle


    【解决方案1】:

    你快到了,只需添加 MIN(Number) 字段。

    SELECT  ID
            , NAME
            , MIN(NUMBER)
            , MIN(IDN)
    FROM    ATable
    GROUP BY
            ID
            , NAME
    

    回应评论

    以下将为您提供MIN(IDN) 的记录,无论该特定记录的编号是多少。

    SELECT  t.*
    FROM    ATable t
            INNER JOIN (        
              SELECT  ID, IDN = MIN(IDN)
              FROM    ATable
              GROUP BY ID
            ) tmin ON tmin.ID = t.ID
                      AND tmin.IDN = t.IDN
    

    【讨论】:

    • 我真的不能这样做,因为我不想要 NUMBER 中的 MIN 值,我不想要 MIN(IDN) 所在行中的值
    • @shin - 一个不幸的巧合,但在你的例子中它匹配,我误解了它。我添加了一个处理它的查询。
    • 是的,它起作用了:D 我花了一段时间,因为我的 ATable 已经是一个很大的选择,加入:D 谢谢 m8 ;D
    • @cyberkiwi,是的,但我认为我们可以假设 IDN 是唯一的。如果不是,添加 DISTINCT 就足够了。
    • 这还不够。外部查询将显示同一 IDN 的 >1 条记录,而无需其他级别的查询
    【解决方案2】:
    DECLARE @TABLE table (ID int, [NAME] varchar(100),NUMBER int ,IDN int)
    insert into @TABLE SELECT 1,'dsad',500600,12
    insert into @TABLE SELECT 1,'dsad',600700, 13
    insert into @TABLE SELECT 2,'kkkk',111222, 56
    insert into @TABLE SELECT 2,'kkkk',333232, 57
    
    select t.ID, t.[Name], t.Number, t.IDN
    from (
       select [NAME],min(IDN) as minIDN
       from @TABLE group by [NAME]
    ) as x inner join @TABLE as t on t.[Name]=x.[Name] and t.IDN = x.minIDN;
    

    【讨论】:

    • +1 但这是 SQL Server 语法。我不认为测试脚本可以移植到 Oracle。
    【解决方案3】:

    仅使用左连接且没有子查询的版本,带有 SQlite3 和 shell 脚本,因为我手头没有任何其他 ATM:

    #!/bin/sh
    
    rm -f test.sqlite
    sqlite3 test.sqlite << AAA
    CREATE TABLE test (id int, name text, number int, idn int);
    INSERT INTO test VALUES(1,'dsad',500600,12);
    INSERT INTO test VALUES(1,'dsad',600700,13);
    INSERT INTO test VALUES(2,'kkkk',111222,56);
    INSERT INTO test VALUES(2,'kkkk',333232,57);
    INSERT INTO test VALUES(1,'dsad',600700,9);
    INSERT INTO test VALUES(2,'kkkk',333232,59);
    INSERT INTO test VALUES(2,'cccc',333232,59);
    SELECT a.* FROM test a
        LEFT JOIN test b ON
                a.id=b.id AND
                a.name=b.name
                AND a.idn > b.idn
                WHERE b.id IS NULL;
    AAA
    # Result:
    # 1|dsad|600700|9
    # 2|cccc|333232|59
    # 2|kkkk|111222|56
    

    任何人都可以评论性能更好的地方吗?我认为这也很重要!

    【讨论】:

    • 在没有索引的情况下,在这一小组数据上,您的解决方案比我的解决方案快一倍。在 ID 上添加索引使这两种解决方案同样快。使用 60 条记录,我给出的解决方案(带索引)是这个的六倍。 请注意,我使用的是 SQL Server io Oracle。甲骨文的年限可能会有所不同。 +1。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 2012-09-09
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    • 2021-11-15
    相关资源
    最近更新 更多