Reputation: 2144
(Editing my post with data and expected result as per replies.)
I have a table which looks as follows. I would like to compute the difference in Score
between two adjacent records.
ID TimeStamp Score
1002010 9/26/2015 11:24:08 PM 32
1002010 9/28/2015 10:12:57 PM 38
This is what I have tried.
SELECT
[current].ID,
[current].Score,
ISNULL(convert(int,[next].Score), 0) - convert(int,[current].Score)
FROM
RiskPredLog AS [current]
LEFT JOIN
RiskPredLog AS [next] ON [next].ID = (SELECT MIN(ID)
FROM TableName
WHERE ID > [current].ID)
WHERE
[current].ID = '1002010'
But I always get the difference to be -1.
Expected result
ID TimeStamp Score
-----------------------------------------------
1002010 9/26/2015 11:24:08 PM NULL
1002010 9/28/2015 10:12:57 PM 6
Upvotes: 0
Views: 145
Reputation: 668
You can try this:
SELECT r.ID,
r.Score,
r.Score - ISNULL(LEAD(r.Score) OVER (ORDER BY r.TimeStamp DESC),0) AS ComputedScore
FROM RiskPredLog r
Upvotes: 0
Reputation: 2097
You can implement ROW_NUMBER()
in place of lead/lag
if you are using pre-2012 SQL Server:
SELECT
[current].ID,
[current].Score,
ISNULL(convert(int,[next].Score), 0) - convert(int,[current].Score)
FROM
(Select *,ROW_NUMBER() OVER (ORDER BY ID,TimeStamp) as rn from RiskPredLog) AS [current]
LEFT JOIN
(Select *,ROW_NUMBER() OVER (ORDER BY ID,TimeStamp) as rn from RiskPredLog) AS [next]
ON [next].rn = [current].rn + 1
Upvotes: 0
Reputation: 49260
You can use lead
to get the value from the next row and use it for subtraction. Note that this function is available in sql server 2012 and later versions.
If you need null
to be the result when there is no leading row, remove the isnull
condition.
SELECT
ID,
Score,
ISNULL(convert(int, lead(Score) over(partition by id order by timestamp)), 0)
- convert(int, Score)
FROM RiskPredLog
-- where ID = '1002010'
Upvotes: 1