How to determine employee salary increases from consecutive contract lines?

I got a problem in my request:

My data to store a table like

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

      

I would like to write a query like below:

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  
-------------------------------------------------------------------------

      

The column increase is calculated for the current contract minus the previous contract

I am using SQL Server 2008 R2

+3


source to share


1 answer


Unfortunately 2008R2 does not have access to LAG

, but you can simulate the effect of getting the previous row ( prev

) in the current row area ( cur

), using RANKing and self join the previous ranked row, in the same section using 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;

      

(If the ContractId always grows fine, we won't need it ROW_NUMBER

and can join the ContractIds increment, I wouldn't want to make that assumption).

SqlFiddle here

Edit



If you have Sql 2012 and later, the LEAD and LAG analytic functions make this kind of query much easier:

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

One trick is that we are calculating the delta increments in the salary, so for the first employee contract we need to return the current salary in order Salary - Salary = 0

for the first increase.

+2


source







All Articles