Sql Server查找下一个最近更改的记录

时间:2011-01-27 20:24:50

标签: sql sql-server tsql

在我的员工历史记录表中,我试图找到薪水是什么,然后是什么改为。每个Salary更改都会插入一条新记录,因为新工资被视为新的“工作”,因此它附加了开始日期和结束日期。我可以选择所有这些日期,但我一直在重复,因为我似乎无法将当前记录与该员工的最新记录进行比较。 (如果这是有道理的)

我希望结果符合以下几行:

Employe Name, OldSalary, NewSalary, ChangeDate(EndDate)
Joe           40,000     42,000     01/10/2011

示例数据类似于

EmployeeHistId     EmpId     Name    Salary      StartDate     EndDate
1                  45        Joe     40,000.00   01/05/2011    01/10/2011
2                  45        Joe     42,000.00   01/11/2011    NULL
3                  46        Bob     20,000.00   01/12/2011    NULL

3 个答案:

答案 0 :(得分:3)

瑞士军队ROW_NUMBER()拯救:

with cte as (
select EmployeeHistId     
  , EmpId     
  , Name    
  , Salary      
  , StartDate     
  , EndDate
  , row_number () over (
      partition by EmpId order by StartDate desc) as StartDateRank
from EmployeeHist)
select n.EmpId
  , n.Name
  , o.Salary as OldDalary
  , n.Salary as NewSalary
  , o.EndData as ChangeDate
from cte n
join cte o on o.EmpId = n.EmpId 
  and n.StartDateRank = 1
  and o.StartDateRank = 2;

使用外部联接来获得从未获得加薪的员工。

由于数据纯度问题,如果StartDate和EndDate重叠,这些类型的查询总是很棘手。

答案 1 :(得分:1)

我认为StartDate和EndDate对于新作业和以前的作业是相同的。 如果是这样,试试这个。

SELECT a.Name AS EmployeeName, b.Salary AS NewSalary a.Salary AS NewSalary, a.StartDate AS ChangeDate
  FROM EMPLOYEE A, EMPLOYEE B
 WHERE a.EmpID = b.EmpID
   AND a.EndDate IS NULL
   AND a.StartDate = b.EndDate

答案 2 :(得分:1)

您可以使用相关联接运算符APPLY来轻松解决这些类型的挑战

select a.name, curr.salary, prev.salary, prev.enddate
from employee e
cross apply ( -- to get the current
   select top(1) *
   from emphist h
   where e.empid = h.empid  -- related to the employee
   order by startdate desc) curr
outer apply ( -- to get the prior, if any
   select top(1) *
   from emphist h
   where e.empid = h.empid  -- related to the employee
     and h.EmployeeHistId <> curr.EmployeeHistId -- prevent curr=prev
   order by enddate desc) prev  -- last ended