创建一个SQL查询以检索最新记录


72

我正在为我的项目团队创建状态板模块。状态板允许用户将其状态设置为进出,也可以提供注释。我打算将所有信息存储在一个表中...数据示例如下:

Date               User         Status    Notes
-------------------------------------------------------
1/8/2009 12:00pm   B.Sisko      In        Out to lunch    
1/8/2009 8:00am    B.Sisko      In  
1/7/2009 5:00pm    B.Sisko      In    
1/7/2009 8:00am    B.Sisko      In    
1/7/2009 8:00am    K.Janeway    In   
1/5/2009 8:00am    K.Janeway    In    
1/1/2009 8:00am    J.Picard     Out       Vacation  

我想查询数据并返回每个用户的最新状态,在这种情况下,我的查询将返回以下结果:

Date               User         Status    Notes
-------------------------------------------------------  
1/8/2009 12:00pm   B.Sisko      In        Out to lunch    
1/7/2009 8:00am    K.Janeway    In   
1/1/2009 8:00am    J.Picard     Out       Vacation  

我试图找出TRANSACT-SQL来实现这一目标?任何帮助,将不胜感激。

Answers:


83

聚集在子查询派生表中,然后加入该表。

 Select Date, User, Status, Notes 
    from [SOMETABLE]
    inner join 
    (
        Select max(Date) as LatestDate, [User]
        from [SOMETABLE]
        Group by User
    ) SubMax 
    on [SOMETABLE].Date = SubMax.LatestDate
    and [SOMETABLE].User = SubMax.User 

4
这称为派生表。
SurroundedByFish09年

7
请注意,派生表的结尾是否为{LatestDate,User}的副本
alphadogg 2013年

2
除非数据库保证,否则不要依赖唯一性。我永远不会在SQLMenace的答案上推荐这种方法,因为结果中的意外重复会导致非常意外的下游行为。(此处失败的最佳示例是脚本更新,该更新导致多个状态更改同时发生)
Andrew Hill

76

换句话说,这将只扫描一次表,而不是两次(如果您使用子查询)

仅sql server 2005及更高版本

select Date, User, Status, Notes 
from (
       select m.*, row_number() over (partition by user order by Date desc) as rn
       from [SOMETABLE] m
     ) m2
where m2.rn = 1;

魔术,我能够解决棘手的查询,涉及连接3个表,并根据此代码为每种类型仅选择最新条目。谢谢!
索普利2013年

1
这在执行计划中的成本与接受的答案相同,但是在您需要按多个列进行分组(例如orgID,Month,Year)时,此答案在语义上更简洁。
gooddadmike 2014年

这将根据顺序从所有相等的记录中随机选择一个记录。
安德鲁·希尔

11

派生表可以工作,但是如果是SQL 2005,则CTE和ROW_NUMBER可能更干净:

WITH UserStatus (User, Date, Status, Notes, Ord)
as
(
SELECT Date, User, Status, Notes, 
     ROW_NUMBER() OVER (PARTITION BY User ORDER BY Date DESC)
FROM [SOMETABLE]
)

SELECT User, Date, Status, Notes from UserStatus where Ord = 1

这也将有助于显示每个用户的最新x状态。


6

另一个简单的方法:

SELECT Date, User, Status, Notes  
FROM Test_Most_Recent 
WHERE Date in ( SELECT MAX(Date) from Test_Most_Recent group by User)

3
如果两个用户同时更新其状态,此查询不会出错,但是那一次不是其中一个的最新活动吗?
SooDesuNe

Mahesh,您需要考虑@SooDesuNe的评论来更新您的答案。
Sunny R Gupta 2014年

如果可以帮助,请不要在WHERE子句中使用SELECTS。除非是一次性的事情,否则您需要查找。如果这要在存储的proc中进行,则会大大增加返回结果的时间。特别是在大桌子上。
Argyle Ghost

0

向每个记录添加一个自动递增的主键,例如UserStatusId。

然后您的查询可能如下所示:

select * from UserStatus where UserStatusId in
(
    select max(UserStatusId) from UserStatus group by User
)

日期用户状态注释

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.