Reputation: 1771
I have a SQL 2008 database table like this
name score
-----------------------
steve 207
steve 205
steve 200
steve 139
I want to get the difference between the rows. eqn = [row - (row + 1)] so I would ideally want it to be,
steve 2 //207 - 205
steve 5 //205 - 200
steve 61 //200 - 139
steve 139 //139 - 0
What is the best way to do this? Thanks!
Upvotes: 28
Views: 41196
Reputation: 52675
This is one way to do it
with cte as
(SELECT
ROW_NUMBER() OVER (PARTITION BY table.name ORDER BY id) row,
name,
score
FROM table)
SELECT
a.name ,
a.score - ISNULL(b.score,0)
FROM
cte a
LEFT JOIN cte b
on a.name = b.name
and a.row = b.row+1
Upvotes: 27
Reputation: 78561
Another way to do it is using lag():
SELECT
name,
score - coalesce(lag(score) over (partition by name order by id), 0)
FROM table
ORDER BY name, id
The lag() function doesn't seem to be available in TSQL but this workaround is suggested in the comments:
select name,
score - coalesce(
MIN(score) OVER (PARTITION BY name ORDER BY id
ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
, 0) as diff
from table
order by name, id
Upvotes: 16