从数据库中检索每组中的最后一条记录 - SQL Server 2005/2008

问题描述 投票:0回答:2

我做了一些搜索,似乎无法得到我正在寻找的结果。基本上,我们整个公司有四个不同的管理系统,我正在定期合并每个系统的所有数据。我的目标是每小时将数据更新到中央数据库中。这是我正在使用的示例数据集:

COMPUTERNAME | SERIALNUMBER | USERNAME | LASTIP | LASTUPDATE | SOURCE
TEST1 | 1111 | BOB | 1.1.1.1 | 1/17/2011 01:00:00 | MGMT_SYSTEM_1
TEST1 | 1111 | BOB | 1.1.1.1 | 1/18/2011 01:00:00 | MGMT_SYSTEM_2
TEST1 | 1111 | PETER | 1.1.1.11 | 1/19/2011 01:00:00 | MGMT_SYSTEM_3
TEST2 | 2222 | GEORGE | 1.1.1.2 | 1/17/2011 01:00:00 | MGMT_SYSTEM_1
TEST3 | 3333 | TOM | 1.1.1.3 | 1/19/2011 01:00:00 | MGMT_SYSTEM_2
TEST4 | 4444 | MIKE   | 1.1.1.4 | 1/17/2011 01:00:00 | MGMT_SYSTEM_1
TEST4 | 4444 | MIKE   | 1.1.1.41 | 1/19/2011 01:00:00 | MGMT_SYSTEM_3
TEST5 | 5555 | SUSIE  | 1.1.1.5 | 1/19/2011 01:00:00 | MGMT_SYSTEM_1

所以我想查询这个主表并只检索最新记录(基于 LASTUPDATE),这样我就可以获得有关该系统的最新信息。问题是每个数据库中可能有一个系统,但当然它们永远不会具有相同的精确更新时间。

我希望得到这样的东西:

TEST1 | 1111 | PETER | 1.1.1.11 | 1/19/2011 01:00:00 | MGMT_SYSTEM_3
TEST2 | 2222 | GEORGE | 1.1.1.2 | 1/17/2011 01:00:00 | MGMT_SYSTEM_1
TEST3 | 3333 | TOM | 1.1.1.3 | 1/19/2011 01:00:00 | MGMT_SYSTEM_2
TEST4 | 4444 | MIKE   | 1.1.1.41 | 1/19/2011 01:00:00 | MGMT_SYSTEM_3
TEST5 | 5555 | SUSIE  | 1.1.1.5 | 1/19/2011 01:00:00 | MGMT_SYSTEM_1

我尝试过使用 MAX 函数,但只能检索一列。我无法在子查询中使用它,因为我没有唯一的 ID 字段来提供最后更新的记录。其中一个系统是 MySQL 数据库,MySQL 中的 MAX 函数实际上会按照我需要的方式工作,每个 GROUP BY 只返回一条记录,但它在 SQL Server 中不起作用。

我想我需要使用 MAX 和 LEFT JOIN,但到目前为止我的尝试失败了。

我们将非常感谢您的帮助。在过去的 3-4 个小时里,我一直在绞尽脑汁试图得到一个有效的查询。该主表位于 SQL Server 2005 服务器上。

谢谢!

sql-server-2005 t-sql sql-server-2008 distinct
2个回答
108
投票
;with cteRowNumber as (
   select COMPUTERNAME, SERIALNUMBER, USERNAME, LASTIP, LASTUPDATE, SOURCE,
   row_number() over(partition by COMPUTERNAME order by LASTUPDATE desc) as RowNum
        from YourTable
)
select COMPUTERNAME, SERIALNUMBER, USERNAME, LASTIP, LASTUPDATE, SOURCE
    from cteRowNumber
    where RowNum = 1

51
投票

在 SQL Server 中,性能最佳的解决方案通常是相关子查询:

select t.*
from t
where t.lastupdate = (select max(t2.lastupdate)
                      from t t2
                      where t2.computername = t.computername
                     );

特别是,这可以利用

(computername, lastupdate)
上的索引。 从概念上讲,这比
row_number()
更快的原因是因为此查询只是过滤掉不匹配的行。
row_number()
版本需要在过滤之前将行号附加到所有行 - 这是更多的数据处理。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.