SQL Server:只有GROUP BY中的最后一个条目

时间:2009-01-13 13:30:40

标签: sql sql-server group-by

我在MSSQL2005中有下表

id | business_key | result
1 | 1 | 0
2 | 1 | 1
3 | 2 | 1
4 | 3 | 1
5 | 4 | 1
6 | 4 | 0

现在我想根据business_key进行分组,返回ID最高的完整条目。 所以我的预期结果是:

business_key | result
1 | 1
2 | 1
3 | 1
4 | 0

我敢打赌,有一种方法可以实现这一点,我现在看不到它。

5 个答案:

答案 0 :(得分:11)

另一种解决方案,它可以为您提供更好的性能(测试两种​​方式并检查执行计划):

SELECT
     T1.id,
     T1.business_key,
     T1.result
FROM
     dbo.My_Table T1
LEFT OUTER JOIN dbo.My_Table T2 ON
     T2.business_key = T1.business_key AND
     T2.id > T1.id
WHERE
     T2.id IS NULL

此查询假定ID是唯一值(至少对于任何给定的business_key)并且它设置为NOT NULL。

答案 1 :(得分:4)

select
  drv.business_key,
  mytable.result
from mytable
  inner join
  (
    select 
      business_key, 
      max(id) as max_id
    from mytable
    group by
      business_key
  ) as drv on
    mytable.id = drv.max_id

答案 2 :(得分:2)

试试这个

select  business_key, 
        result
from    myTable
where   id in 
        (select max(id)
        from    myTable
        group by business_key)

编辑:我创建了表来测试我的代码。我将其包含在下面以防其他人想要测试它。

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[myTable](
    [id] [int] NOT NULL,
    [business_key] [int] NOT NULL,
    [result] [int] NOT NULL
) ON [PRIMARY]
go

insert into myTable values(1,1,0);
insert into myTable values(2,1,1);
insert into myTable values(3,2,1);
insert into myTable values(4,3,1);
insert into myTable values(5,4,1);
insert into myTable values(6,4,0);

select  * from mytable

答案 3 :(得分:2)

select business_key, 
       result
    from 
    (select id, 
        business_key, 
        result, 
        max(id) over (partition by business_key) as max_id
    from mytable) x
where id = max_id

答案 4 :(得分:1)

这是一篇较旧的帖子,但与我目前正在做的事情有关(2013年)。如果您获得更大的数据集(在大多数数据库中是典型的),各种查询的性能(查看执行计划)会说明很多。首先,我们创建一个“TALLY表”来随机生成数字,然后使用任意公式为“MyTable”创建数据:

CREATE TABLE #myTable(
    [id] [int] NOT NULL,
    [business_key] [int] NOT NULL,
    [result] [int] NOT NULL,
    PRIMARY KEY (Id)
) ON [PRIMARY];

; WITH
    -- Tally table Gen            Tally Rows:     X2                X3
t1 AS (SELECT 1 N UNION ALL SELECT 1 N),    -- 4            ,    8
t2 AS (SELECT 1 N FROM t1 x, t1 y),            -- 16            ,    64
t3 AS (SELECT 1 N FROM t2 x, t2 y),            -- 256            ,    4096
t4 AS (SELECT 1 N FROM t3 x, t3 y),            -- 65536        ,    16,777,216
t5 AS (SELECT 1 N FROM t4 x, t4 y),            -- 4,294,967,296,    A lot
Tally AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) N
          FROM t5 x, t5 y)

INSERT INTO #MyTable 
SELECT N, CAST(N/RAND(N/8) AS bigINT)/5 , N%2
FROM Tally
WHERE N < 500000

接下来,我们运行三种不同类型的查询来检查性能(如果您使用的是SQL Server Management Studio,请启用“实际执行计划”):

SET STATISTICS IO ON
SET STATISTICS TIME ON
----- Try #1 
select  'T1' AS Qry, id, business_key, 
        result
from    #myTable
where   id in 
        (select max(id)
        from    #myTable
        group by business_key)

---- Try #2 
select 'T2' AS Qry, id, business_key, 
       result
    from 
    (select id, 
        business_key, 
        result, 
        max(id) over (partition by business_key) as max_id
    from #mytable) x
where id = max_id

---- Try #3 
;with cteRowNumber as (
    select id, 
        business_key, 
        result,
           row_number() over(partition by business_key order by id desc) as RowNum
        from #mytable
)

SELECT 'T3' AS Qry, id, business_key, 
       result
FROM cteRowNumber
WHERE RowNum = 1

清理:

IF OBJECT_ID(N'TempDB..#myTable',N'U') IS NOT NULL 
    DROP TABLE #myTable;
    SET STATISTICS IO OFF
SET STATISTICS TIME OFF

您会发现,查看执行计划,“Try 1”具有最佳“查询成本”和最低CPU时间,但“Try 3”具有最少的读取和CPU时间也不错。我建议使用CTE方法进行最少的读取