如何确定连续合约行的员工薪酬增加?

时间:2015-05-25 04:40:27

标签: sql sql-server-2008 tsql

我的查询出了问题:

我的表存储数据

ContractID | Staff_ID | EffectDate  | End Date   | Salary | active
-------------------------------------------------------------------------
1          | 1        | 2013-01-01  | 2013-12-30 | 100    | 0
2          | 1        | 2014-01-01  | 2014-12-30 | 150    | 0
3          | 1        | 2015-01-01  | 2015-12-30 | 200    | 1
4          | 2        | 2014-05-01  | 2015-04-30 | 500    | 0
5          | 2        | 2015-05-01  | 2016-04-30 | 700    | 1

我想写一个如下的查询:

ContractID | Staff_ID | EffectDate  | End Date   | Salary | Increase
-------------------------------------------------------------------------
1          | 1        | 2013-01-01  | 2013-12-30 | 100    | 0
2          | 1        | 2014-01-01  | 2014-12-30 | 150    | 50
3          | 1        | 2015-01-01  | 2015-12-30 | 200    | 50
4          | 2        | 2014-05-01  | 2015-04-30 | 500    | 0
5          | 2        | 2015-05-01  | 2016-04-30 | 700    | 200  
-------------------------------------------------------------------------

增加列按当前合约减去上一份合约计算

我使用的是sql server 2008 R2

1 个答案:

答案 0 :(得分:2)

不幸的是,2008R2无法访问LAG,但您可以模拟在当前行(prev的范围内获取上一行(cur)的效果),使用RANKing和自联接到上一个排名的行,在Staff_ID的同一分区中):

With CTE AS 
(
    SELECT [ContractID], [Staff_ID], [EffectDate], [End Date], [Salary],[active], 
    ROW_NUMBER() OVER (Partition BY Staff_ID ORDER BY ContractID) AS Rnk
    FROM Table1
)
SELECT cur.[ContractID], cur.[Staff_ID], cur.[EffectDate], cur.[End Date],
    cur.[Salary], cur.Rnk,
    CASE WHEN (cur.Rnk = 1) THEN 0 -- i.e. baseline salary
         ELSE cur.Salary - prev.Salary END AS Increase
FROM CTE cur
    LEFT OUTER JOIN CTE prev
    ON cur.[Staff_ID] = prev.Staff_ID and cur.Rnk - 1 = prev.Rnk;

(如果ContractId总是完全递增,我们就不需要ROW_NUMBER并且可以加入ContractIds,我不想做出这个假设。)

SqlFiddle here

修改

如果你有Sql 2012及更高版本,LEAD and LAG Analytic Functions会使这种查询更加简单:

SELECT [ContractID], [Staff_ID], [EffectDate], [End Date], [Salary], 
Salary - LAG(Salary, 1, Salary) OVER (Partition BY Staff_ID ORDER BY ContractID) AS Incr
FROM Table1

Updated SqlFiddle

这里的一个技巧是我们正在计算工资增量增量,因此对于第一个员工合同,我们需要返回当前工资,以便Salary - Salary = 0首次增加。