在我的员工历史记录表中,我试图找到薪水是什么,然后是什么改为。每个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
答案 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