SQL Server:为每个员工选择最后一条记录

时间:2017-11-05 12:05:13

标签: sql sql-server sql-server-2008

以下查询在多个终端(网点)获取员工登录(出勤)信息。

例如,如果一名员工在不同的日子访问过三家分店,我想获取最后的日志信息(他访问过的最后一个分店)。

查询:

select 
    [EmpCode],
    Name,
    max(convert(datetime, [LogDate])) as [Last Log date],
    Outlet.abr as [Last Log Location]
from
    AccessLog
inner join
    GEmp on GEmp.EmpCode = AccessLog.EmployeeID
inner join
    Outlet on Outlet.Code = AccessLog.TerminalID
where   
    InOut = '0'
group by 
    GEmp.EmpCode, Name, Outlet.abr

输出:

EmpCode Name    Last Log date   Last Log Location
--------------------------------------------------
362334  Emp1    10/4/2017       loc1
362334  Emp1    11/4/2017       loc2
362334  Emp1    5/30/2017       loc3
362336  Emp2    10/6/2017       loc1
362336  Emp2    11/4/2017       loc2

期望的输出:

EmpCode Name    Last Log date   Last Log Location
-------------------------------------------------
362334  Emp1    11/4/2017        loc2
362336  Emp2    11/4/2017        loc2

2 个答案:

答案 0 :(得分:0)

我无法测试,但这是正确的方法:

Select *
    From 
   (
   Select ilv.*, row_number () over (partition by empcode order by logdate desc)
   r
   From
   (...) ilv 
   ) ilv2
   Where r=1

唯一需要注意的是,如果多次出现相同的最后日期,则需要打破平局。因为它表明上面的查询没有一个,因此不是幂等的。

答案 1 :(得分:0)

使用row_number()

select e.Name, al.LogDate, o.abr
from (select al.*,
             row_number() over (partition by al.EmployeeId order by al.LogDate desc) as seqnum
      from AccessLog al
      where al.InOut = 0
     ) al join
     GEmp e
     on e.EmpCode = al.EmployeeID join
     Outlet o
     on o.Code = al.TerminalID
where al.seqnum = 1;

注意:

  • 我添加了表别名,这是表的缩写。这使查询更容易编写和阅读。
  • 我对所有列名称进行了限定(希望正确!),因此很清楚数据的来源。
  • 我删除了'0'周围的单引号。我的假设是该值实际上是数字。
  • 问题的解决方案是在子查询中使用row_number()