简体   繁体   English

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

[英]SQL Server : select last record for each employee

The below query gets employees log (attendance) information at multiple terminals (outlets). 以下查询获取员工在多个终端(插座)的日志(出勤)信息。

For example if one employee visited three outlets in different days I want to get last log information (last outlet he visited). 例如,如果一位员工在不同的日期访问了三个销售点,我想获取最后的日志信息(他访问的最后一个销售点)。

Query: 查询:

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

Output: 输出:

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

Desired output: 所需的输出:

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

I'm not able to test but here is the correct method: 我无法测试,但这是正确的方法:

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

Only note is if the same last date occurs multiple times, you will need a tie breaker. 唯一需要注意的是,如果同一日期多次发生,则需要平局。 As it stands that query above does not have one and thus is not idempotent. 从目前的情况来看,上面的查询没有一个查询,因此不是幂等的。

Use row_number() : 使用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;

Notes: 笔记:

  • I added table aliases which are abbreviations for the table. 我添加了表别名,这是表的缩写。 This makes the query easier to write and to read. 这使查询更易于编写和阅读。
  • I qualified all column names (hopefully correctly!) so it is clear where the data is coming from. 我对所有列名进行了限定(希望正确!),因此很清楚数据来自何处。
  • I removed the single quotes around '0' . 我删除了'0'周围的单引号。 My assumption is that the value is actually numeric. 我的假设是该值实际上是数字。
  • The solution to your problem is the use of row_number() in the subquery. 解决问题的方法是在子查询中使用row_number()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM