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

mat*_*uma 56 sql t-sql derived-table

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

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  
Run Code Online (Sandbox Code Playgroud)

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

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  
Run Code Online (Sandbox Code Playgroud)

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

cms*_*sjr 75

子查询派生表中聚合,然后加入它.

 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 
Run Code Online (Sandbox Code Playgroud)

  • 如果派生表最终为{LatestDate,User}重复,请小心 (6认同)
  • 这称为派生表. (4认同)
  • 除非数据库保证,否则永远不要依赖于唯一性; 我绝不会推荐这种方法超过SQLMenace的答案,因为结果中的意外重复会导致非常意外的下游行为.(这里失败的最好例子是脚本更新,导致一些状态变化同时降落) (2认同)

SQL*_*ace 62

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

只有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;
Run Code Online (Sandbox Code Playgroud)

  • 这在执行计划中的成本与接受的答案相同,但是当您需要按多个列(例如 orgID、Month、Year)进行分组时,此答案在语义上更清晰。 (2认同)

小智 10

派生表可以工作,但如果这是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
Run Code Online (Sandbox Code Playgroud)

这还有助于显示来自每个用户的最新x状态.


小智 5

另一个简单方法:

SELECT Date, User, Status, Notes  
FROM Test_Most_Recent 
WHERE Date in ( SELECT MAX(Date) from Test_Most_Recent group by User)
Run Code Online (Sandbox Code Playgroud)

  • 如果两个用户同时更新其状态,那么此查询是否会出错,但该时间不是其中一个用户的最新活动? (3认同)