SQL窗口函数实战:排名与偏移技巧
窗口函数
知识点引入
窗口函数over([partition by 字段名][order by 字段名 asc|desc])
语法讲解
over()中两个子句为可选项,partition by指定分区依据,order by指定排序依据
排序窗口函数
rank()over()
dense_rank()over()
row_number()over()
偏移分析函数
lag(字段名,偏移量[,默认值])over()
lead(字段名,偏移量[,默认值])over()
查询每一年S140000021选区中所有候选人所在的团体(party)和得票数(votes),并对每一年中的所有候选人根据选票数的高低赋予名次,选票数最高则为1,第二名则为2,后续依此类推,最后根据团体(party)和年份(yr)的排序
select yr,party,votes,rank()over(partition by order by votes desc)as posn
from ge
where constituency='S140000021'
order by party,yr
窗口函数在having后面执行
-
ROW_NUMBER() OVER ()
功能:为结果集中的每一行提供一个连续且唯一的整数标识。
特点:即使存在重复值(即根据排序条件有相同的值),每行也会被赋予不同的编号。
用途:常用于需要唯一标识符或简单排序的情况。
示例:
SELECT
id, name, score,
ROW_NUMBER() OVER (ORDER BY score DESC) as row_num
FROM students; -
RANK() OVER ()
功能:给结果集中的每一行分配一个排名,如果有并列名次,则跳过后续的排名数字。
特点:当遇到相同值时,会给出相同的排名,但下一个排名将跳跃以保持正确的总数。
用途:适用于需要考虑并列情况的比赛、成绩等场景。
示例:
SELECT
id, name, score,
RANK() OVER (ORDER BY score DESC) as rank
FROM students;
假设分数为 [90, 85, 85, 80] 的学生,他们的排名将是 1, 2, 2, 4。 -
DENSE_RANK() OVER ()
功能:类似于 RANK() 函数,但它不会跳过任何排名数字,而是紧随其后继续编号。
特点:如果有多行具有相同的值,则这些行将获得相同的排名;但紧接着的下一行将直接使用下一个整数作为排名。
用途:适合于那些不希望因为并列而造成排名空缺的情形。
示例:
SELECT
id, name, score,
DENSE_RANK() OVER (ORDER BY score DESC) as dense_rank
FROM students;
对于同样的分数 [90, 85, 85, 80],使用 DENSE_RANK() 得到的排名将是 1, 2, 2, 3。
总结
如果你需要简单的连续编号,选择 ROW_NUMBER()。
当你的应用逻辑允许或者需要处理并列排名,并且可以接受排名间的间隔时,使用 RANK()。
如果你希望处理并列排名但不想让排名间出现空隙,那么 DENSE_RANK() 将是最合适的选择。
查询法国和德国1月每天新增确诊人数,最后显示国家名、标准日期(2020-01-27),当前截至时间累计确诊人数、昨天截至时间累计确诊人数、每天新增确诊人数,按照截至时间排序
select name,date-format(whn,'%Y-%m-%d')date,comfirmed,
lag(comfirmed,1)over(partition by name order by whn)
,(confirmed-lag(comfirmed,1)over(partition by name order by whn)
from cvoid
where name in('France','Germany')and month(whn)=1
order by whn
LAG() 和 LEAD() 是 SQL 中的窗口函数,用于在结果集中访问当前行之前或之后的行的数据。这两个函数在处理时间序列数据、计算变化率、比较相邻行等方面非常有用。
语法
LAG(字段名, 偏移量[, 默认值]) OVER (PARTITION BY … ORDER BY …)
LEAD(字段名, 偯移量[, 默认值]) OVER (PARTITION BY … ORDER BY …)
参数说明
字段名:要访问的列名。
偏移量:指定要访问的行相对于当前行的位置。正数表示向后(对于 LAG)或向前(对于 LEAD),负数则相反。
默认值:如果指定的偏移量超出了分区范围,则返回这个默认值。如果不指定,默认值为 NULL。
PARTITION BY:可选参数,用于将数据分成不同的分区。
ORDER BY:必选参数,用于确定行的顺序。
