Sql Server 查找下一个最近更改的记录
Posted
技术标签:
【中文标题】Sql Server 查找下一个最近更改的记录【英文标题】:Sql Server Find Next Most Recent Changed Record 【发布时间】:2011-01-27 20:24:50 【问题描述】:在我的员工历史记录表中,我试图找出薪水是多少,然后又变成了什么。每次薪水更改都会插入一条新记录,因为新薪水被认为是新的“工作”,因此它附有开始和结束日期。我可以很好地选择所有这些日期,但我不断重复,因为我似乎无法将当前记录与该员工最近的先前记录进行比较。 (如果有道理的话)
我希望结果类似于:
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
【问题讨论】:
你能指望每个 EmpID 只有一个NULL
EndDate 吗?
但是你可以让所有 EndDates 都为空(员工离开),这会使它作为谓词无效。哪个版本的 SQL Server?
只有每个员工最近的记录才会有一个空结束日期。它的 sql server 2005。
【参考方案1】:
瑞士军队 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 重叠。
【讨论】:
开始日期和结束日期不应重叠,但我不能保证。该解决方案是否涵盖了这种可能性? 我将发布与您相同的解决方案,但有一个不同之处:不是按 StartDate 排序,而是按CASE EndDate WHEN NULL THEN 0 ELSE 1 END, EndDate DESC
排序,这样您将获得最新的 EndDate。重叠无关紧要,您将包括NULL
【参考方案2】:
我假设新工作和以前工作的 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
【讨论】:
我喜欢你的方法,但从他的样本数据来看,情况并非如此...... 可能是where a.employeehistid = b.employeehistid - 1
【参考方案3】:
您可以使用关联连接运算符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
【讨论】:
以上是关于Sql Server 查找下一个最近更改的记录的主要内容,如果未能解决你的问题,请参考以下文章