我在SQL Server 2014 Developer Edition数据库中有一个名为ComputerStatus
的表,如下所示:
ComputerName Status Timestamp
------------ ----------- ------------
client01 Online 2013-04-11 11:00 AM
client01 Online 2013-04-08 10:00 AM
client01 Offline 2013-04-05 09:00 PM
client02 Offline 2013-04-08 10:00 AM
client02 Online 2013-04-03 10:00 AM
client03 Online 2013-04-02 10:00 AM
client03 Offline 2013-04-05 10:00 PM
client03 Online 2013-04-03 12:00 PM
我想要做的是获取每个唯一计算机名称的最新行(基于Timestamp
)行。虽然我对SQL Server查询非常讨厌,但我知道我可以:
select top 1 * from ComputerStatus where ComputerName = 'client01' order by Timestamp descending
ComputerName Status Timestamp
------------ ----------- ------------
client01 Online 2013-04-11 11:00 AM
client02 Offline 2013-04-08 10:00 AM
client03 Offline 2013-04-05 10:00 PM
我知道如何选择单台计算机的最新行。我正在努力解决的部分是如何为表中所有独特的计算机执行此操作。这是否需要我使用SQL游标来迭代表中的唯一计算机名称?或者,是否有更有效的方法来实现这些结果?
答案 0 :(得分:9)
您可以使用RowNumber执行此操作,RowNumber为每一行提供行号。由于您希望基于TimeStamp为每个computerName提供从1开始的行号,我们需要通过Computername对其进行分区
select * from (
select *, ROW_NUMBER() over (partition by ComputerName order by Timestamp desc) as rno
from ComputerStatus
) as T where rno = 1
答案 1 :(得分:3)
另一种选择是这样的:
SELECT cs1.*
FROM ComputerStatus cs1
INNER JOIN (SELECT ComputerName, MAX(Timestamp) as [Timestamp]
FROM ComputerStatus
GROUP BY ComputerName) cs2
ON cs1.ComputerName=cs2.ComputerName and cs1.Timestamp = cs2.Timestamp
子查询将查找计算机名称和最新时间戳,然后外部查询将使用该数据并将其与状态匹配。
但我更喜欢使用ROW_NUMBER()。太方便了!