我正在尝试根据前ROW_NUMBER()
行与当前ROW_NUMBER()
行相比来计算位置变化
我的查询使用的是带有ROW_NUMBER()OVER ..子句的递归cte,它按年份清晰地为我提供了结果的行号。
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
)
此后,我的查询将比较位置以计算行号之间的更改。
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
不幸的是,这不起作用,因为[after]位置始终为空。
这有点难以解释,因此我包含了一个sqlfiddle链接:http://www.sqlfiddle.com/#!18/c7e57e/1
-
2011年明尼苏达州排名1,2012年明尼苏达州排名3,变化为+2
2011年衣阿华州排名第6,2012年衣阿华州排名第4,变化为-2
2011年南达科他州排名第5,2012年南达科他州排名第5,变化为0
谢谢
答案 0 :(得分:1)
想通了。
我错误地尝试在ROW_NUMBER()上进行联接,这将导致联接不匹配,因为行号不一定与状态ID正确对齐。
将其更改为加入year
后,这是计算逐年更改的正确方法,所有这些都汇集在一起。
WITH positions AS (
SELECT
[incidents].state_id, dy.year, MAX(number_of_incidents) AS total_incidents_in_year,
ROW_NUMBER() OVER(PARTITION BY dy.year 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, dy.year
)
SELECT
ds.state_name, ds.state_id, [before].total_incidents_in_year, dy.year,
[before].position AS before_position,
([before].position - [after].position) AS change
FROM
positions AS [before]
LEFT JOIN
positions AS [after] ON [before].state_id = [after].state_id AND [before].year = [after].year + 1
INNER JOIN
years AS dy ON dy.year = [before].year
INNER JOIN
states AS ds on ds.state_id = [before].state_id
ORDER BY
[before].year ASC, [before].total_incidents_in_year DESC