SQL-MySQL窗口函数和单行函数的使用
目录
窗口函数也叫OLAP函数(Online Anallytical Processing),可以对数据进行实时分析处理。窗口函数是面试中考察的重点。窗口函数通常用来解决统计汇总、排名、TopN、连续登录天数等问题。
窗口函数
语法:函数名(字段名) over(partition by <要分列的组> order by <要排序的列> rows between <数据范围>)
数据范围:通过下面的案例来讲解数据范围如何使用。
|
|
分类:按照窗口函数的意义大概可以分为下面 5 类,其中排序函数最为常用。
- 排序函数:
row_number()、rank()、dense_rank()
- 分布函数:
percent_rank()、cume_dist()
- 相对位置函数:
lag(expr,n)、lead(expr,n)
,用于返回某字段的前n
行或后n
行的值。expr
既可以是表达式也可以是列名。 - 绝对位置函数:
first_value(expr)、last_value(expr)、nth_value(expr,n)
,返回第一个或最后一个或第n
个expr
的值。 - 分桶函数:
ntile(x)
另外,聚合函数也可以作为窗口函数使用:
聚合函数:avg(),sum(),min(),max()
排序函数
row_number()
:对每一行分配一个序号,序号连续加1,不会重复。常用于排序。rank()
:给每行分配一个序号,相同值的序号相同,序号不连续。常用于排序。dense_rank()
:给每行分配一个序号,相同值的序号相同,序号连续。常用于排序。
分布函数
percent_rank()
:每行按照公式$(rank-1) / (rows-1)$进行计算。其中,rank
为RANK()
函数产生的序号,rows
为当前窗口的记录总行数。cume_dist()
:分组内小于、等于当前rank
值的行数 / 分组内总行数
相对位置函数
lag(expr,n)
:返回位于当前行的前n
行的值lead(expr,n)
:返回位于当前行的后n
行的值
绝对位置函数
first_value(expr)
:返回第一个expr
的值。last_value(expr)
:返回最后一个expr
的值。nth_value(expr,n)
:返回窗口中第n
个expr
的值。
应用场景 1 举例:求首次登录和末次登录时间
|
|
id | log_dt | f_dt | l_dt |
---|---|---|---|
1 | 2020-11-10 | 2020-11-10 | 2020-11-10 |
1 | 2021-01-20 | 2020-11-10 | 2021-01-20 |
1 | 2021-08-12 | 2020-11-10 | 2021-08-12 |
2 | 2021-12-05 | 2021-12-05 | 2021-12-05 |
2 | 2021-12-29 | 2021-12-05 | 2021-12-29 |
应用场景 2 举例:求部门中工资第二的员工
|
|
id | did | s | s2 |
---|---|---|---|
2 | 1 | 200 | 100 |
1 | 1 | 100 | 100 |
4 | 2 | 400 | 300 |
3 | 2 | 300 | 300 |
6 | 3 | 560 | 500 |
5 | 3 | 500 | 500 |
分桶函数
ntile(n)
:对每个分区继续分成n
组,每组的行数为:分区的总行数 /n
。不常用。
日期时间函数
CURDATE()
或CURRENT_DATE()
返回当前日期NOW()
返回当前系统日期时间YEAR(date)
返回年MONTH(date)
返回月DAY(date)
返回日DATEDIFF(date1,date2)
返回date1 - date2
的日期间隔DATE_FORMAT(datetime ,fmt)
按照字符串fmt
格式化日期datetime
值。%Y
4 位数字表示年份%m
两位数字表示月份(01,02,03,…)%d
两位数字表示月中的天数(01,02…)%H
两位数字表示小时,24小时制(01,02,…)
流程函数
IF(value,t ,f)
如果value
是真,返回t
,否则返回f
IFNULL(value1, value2)
如果value1
不为空,返回value1
,否则返回value2
CASE WHEN
数学函数
ABS(x)
返回x
的绝对值CEIL(x)
返回大于x
的最小整数值FLOOR(x)
返回小于x
的最大整数值MOD(x,y)
返回x/y
的模RAND(x)
返回 0~1 的随机值,x
可以不写ROUND(x,y)
返回参数x
的四舍五入的有y
位的小数的值TRUNCATE(x,y)
返回数字x
截断为y
位小数的结果SQRT(x)
返回x
的平方根POW(x,y)
返回x
的y
次方
字符串函数
CONCAT(S1,S2,......,Sn)
连接S1, S2, ......, Sn
为一个字符串CONCAT_WS(separator, S1, S2, ......, Sn)
同CONCAT(s1, s2, ...)
函数,但是每个字符串之间要加上分隔符 separatorTRIM(s)
去掉字符串s
开始与结尾的空格