I'm trying to calculate the positional change based on the previous rows ROW_NUMBER()
compared to the current ROW_NUMBER()
My query is using a recursive cte with a ROW_NUMBER() OVER .. clause which neatly gives me the row number of the result by its year.
WITH positions AS (
SELECT
[incidents].state_id, [incidents].year_id, MAX(number_of_incidents) AS total_incidents_in_year,
ROW_NUMBER() OVER(PARTITION BY [incidents].year_id ORDER BY MAX(number_of_incidents) DESC) AS position
FROM
[incidents]
INNER JOIN
years AS dy ON dy.year_id = [incidents].year_id
INNER JOIN
states AS ds on ds.state_id = [incidents].state_id
GROUP BY
[incidents].state_id, [incidents].year_id
)
After this my query then compares the positions to calculate the change between the row numbers.
SELECT
ds.state_name, ds.state_id, [before].total_incidents_in_year, dy.year,
[before].position AS before_position, [after].position AS after_position,
([before].position - [after].position) AS change
FROM
positions AS [before]
LEFT JOIN
positions AS [after] ON [before].position = [after].position + 1 AND [before].state_id = [after].state_id AND [before].year_id = [after].year_id
INNER JOIN
years AS dy ON dy.year_id = [before].year_id
INNER JOIN
states AS ds on ds.state_id = [before].state_id
ORDER BY
[before].year_id ASC, [before].total_incidents_in_year DESC
Unfortunately this does not work because the [after] position is always null.
This is a bit hard to explain so I've included a sqlfiddle link : http://www.sqlfiddle.com/#!18/c7e57e/1
--
This image visually explains what I'm trying to achieve
In 2011 Minnesota is in position 1, in 2012 Minnesota is in position 3, the change is +2
In 2011 Iowa is in position 6, in 2012 Iowa is in position 4, the change is -2
In 2011 South Dakota is in position 5, in 2012 South Dakota is in position 5, the change is 0
Thank you