mysql开窗函数rownumber_over partition by开窗函数

mysql开窗函数rownumber_over partition by开窗函数什么是开窗函数?开窗函数是一种用于分析数据的强大功能,MySQL从8.0版本开始支持。开窗函数可以在分组之后的返回多行结果,而聚合函数对于每个组只返回一行。开窗函数有以下几种类型:- 聚合开窗函数:sum,avg,count,max,min等,用于计算基于组的某种聚合值。- 排名开窗函数:row_n

什么是开窗函数?

开窗函数是一种用于分析数据的强大功能,MySQL从8.0版本开始支持。开窗函数可以在分组之后的返回多行结果,而聚合函数对于每个组只返回一行。开窗函数有以下几种类型:

– 聚合开窗函数:sum,avg,count,max,min等,用于计算基于组的某种聚合值。

– 排名开窗函数:row_number,dense_rank,rank等,用于对数据进行排序和排名。

– 值分布开窗函数:first_value,last_value,nth_value等,用于获取数据中的特定值。

– 导航开窗函数:lead,lag等,用于获取数据中的前后值。

1.sum()

sum开窗函数是一种聚合开窗函数,用于计算基于组的某种聚合值,它和聚合函数的不同之处是:sum开窗函数可以在分组之后的返回多行结果,而聚合函数对于每个组只返回一行。sum开窗函数的语法如下:

sum(列名) over (partition by 分组列 order by 排序列)

这表示对分组列进行分组,然后按照排序列进行排序,最后对每个分组内的列名进行求和,并返回每一行的累计和。例如,假设有一个成绩表score,有三个字段:学生s_id,课程c_id,成绩s_score。如果想要计算每个学生在每门课程上的累计成绩,可以使用以下语句:

select s_id, c_id, s_score, sum(s_score) over (partition by s_id order by c_id) as total_score from score;

这样就可以得到类似如下的结果:

s_id

c_id

s_score

total_score

1

1

80

80

1

2

90

170

1

3

85

255

2

1

75

75

2

2

80

155

… … … …

2.avg()

avg开窗函数是一种聚合开窗函数,用于计算基于组的某种聚合值,它和聚合函数的不同之处是:avg开窗函数可以在分组之后的返回多行结果,而聚合函数对于每个组只返回一行。avg开窗函数的语法如下:

avg(列名) over (partition by 分组列 order by 排序列) 

这表示对分组列进行分组,然后按照排序列进行排序,最后对每个分组内的列名进行求平均值,并返回每一行的累计平均值。例如,假设有一个成绩表score,有三个字段:学生s_id,课程c_id,成绩s_score。如果想要计算每个学生在每门课程上的累计平均成绩,可以使用以下语句:

select s_id, c_id, s_score, avg(s_score) over (partition by s_id order by c_id) as avg_score from score; 

这样就可以得到类似如下的结果:

s_id

c_id

s_score

avg_score

1

1

80

80

1

2

90

85

1

3

85

85

2

1

75

75

… … … …

3.count()

count开窗函数是一种聚合开窗函数,用于计算基于组的某种聚合值,它和聚合函数的不同之处是:count开窗函数可以在分组之后的返回多行结果,而聚合函数对于每个组只返回一行。count开窗函数的语法如下:

count(列名) over (partition by 分组列 order by 排序列) 

这表示对分组列进行分组,然后按照排序列进行排序,最后对每个分组内的列名进行计数,并返回每一行的累计计数。例如,假设有一个成绩表score,有三个字段:学生s_id,课程c_id,成绩s_score。如果想要计算每个学生在每门课程上的累计参与人数,可以使用以下语句:

select s_id, c_id, s_score, count(s_score) over (partition by c_id order by s_score) as count_score from score; 

这样就可以得到类似如下的结果:

s_id

c_id

s_score

count_score

1

1

80

2

2

1

75

1

3

1

85

3

… … … …

4.max()

max开窗函数是一种聚合开窗函数,用于计算基于组的某种聚合值,它和聚合函数的不同之处是:max开窗函数可以在分组之后的返回多行结果,而聚合函数对于每个组只返回一行。max开窗函数的语法如下:

max(列名) over (partition by 分组列 order by 排序列) 

这表示对分组列进行分组,然后按照排序列进行排序,最后对每个分组内的列名进行求最大值,并返回每一行的累计最大值。例如,假设有一个成绩表score,有三个字段:学生s_id,课程c_id,成绩s_score。如果想要计算每个学生在每门课程上的累计最高成绩,可以使用以下语句:

select s_id, c_id, s_score, max(s_score) over (partition by c_id order by s_score) as max_score from score; 

这样就可以得到类似如下的结果:

s_id

c_id

s_score

max_score

1

1

80

85

2

1

75

85

3

1

85

85

… … … …

5.min()

min开窗函数是一种聚合开窗函数,用于计算基于组的某种聚合值,它和聚合函数的不同之处是:min开窗函数可以在分组之后的返回多行结果,而聚合函数对于每个组只返回一行。min开窗函数的语法如下:

min(列名) over (partition by 分组列 order by 排序列) 

这表示对分组列进行分组,然后按照排序列进行排序,最后对每个分组内的列名进行求最小值,并返回每一行的累计最小值。例如,假设有一个成绩表score,有三个字段:学生s_id,课程c_id,成绩s_score。如果想要计算每个学生在每门课程上的累计最低成绩,可以使用以下语句:

select s_id, c_id, s_score, min(s_score) over (partition by c_id order by s_score) as min_score from score;

这样就可以得到类似如下的结果:

s_id

c_id

s_score

min_score

1

1

80

75

2

1

75

75

3

1

85

75

… … … …

6.row_number()

row_number开窗函数是一种排序开窗函数,用于为每一行分配一个序号,从1开始递增。row_number开窗函数的语法如下:

row_number() over (partition by 分组列 order by 排序列) 

这表示对分组列进行分组,然后按照排序列进行排序,最后对每个分组内的行进行编号。例如,假设有一个员工表employee,有三个字段:部门d_id,姓名e_name,薪水e_salary。如果想要计算每个部门的员工薪水排名,可以使用以下语句:

select d_id, e_name, e_salary, row_number() over (partition by d_id order by e_salary desc) as rank from employee; 

这样就可以得到类似如下的结果:

d_id

e_name

e_salary

rank

1

Alice

5000

1

1

Bob

4000

2

1

Carol

3000

3

… … … …

7.dense_rank()

dense_rank开窗函数是一种排序开窗函数,用于为每一行分配一个排名,而排名值没有间隙。dense_rank开窗函数的语法如下:

dense_rank() over (partition by 分组列 order by 排序列) 

这表示对分组列进行分组,然后按照排序列进行排序,最后对每个分组内的行进行排名。如果分区有两个或更多具有相同排名值的行,则为这些行中的每一行分配相同的排名。与rank开窗函数不同,dense_rank开窗函数始终返回连续的排名值。例如,假设有一个商品表product,有三个字段:类别p_type,名称p_name,价格p_price。如果想要计算每个类别的商品价格排名,可以使用以下语句:

select p_type, p_name, p_price, dense_rank() over (partition by p_type order by p_price desc) as rank from product; 

这样就可以得到类似如下的结果:

p_type

p_name

p_price

rank

A

X

100

1

A

Y

80

2

A

Z

80

2

… … … …

8.rank()

rank开窗函数是一种排序开窗函数,用于为每一行分配一个排名,而排名值有间隙。rank开窗函数的语法如下:

rank() over (partition by 分组列 order by 排序列) 

这表示对分组列进行分组,然后按照排序列进行排序,最后对每个分组内的行进行排名。如果分区有两个或更多具有相同排名值的行,则为这些行中的每一行分配相同的排名。与dense_rank开窗函数不同,rank开窗函数会跳过重复的排名值。例如,假设有一个商品表product,有三个字段:类别p_type,名称p_name,价格p_price。如果想要计算每个类别的商品价格排名,可以使用以下语句:

select p_type, p_name, p_price, rank() over (partition by p_type order by p_price desc) as rank from product; 

这样就可以得到类似如下的结果:

p_type

p_name

p_price

rank

A

X

100

1

A

Y

80

2

A

Z

80

2

… … … …

9.first_value()

first_value开窗函数是一种返回窗口框架,分区或结果集的第一行的值的函数。first_value开窗函数的语法如下:

first_value(表达式) over ([partition by 分组列] [order by 排序列] [frame_clause]) 

这表示对分组列进行分组,然后按照排序列进行排序,最后返回每个分组内的第一行的表达式的值。如果没有指定frame_clause,则默认为range between unbounded preceding and current row,即从分区开始到当前行。例如,假设有一个员工表employee,有四个字段:部门dept_no,姓名emp_name,工资salary,小时hourly_rate。如果想要计算每个部门的最高工资和最高小时率,并显示每个员工与之的差距,可以使用以下语句:

select dept_no, emp_name, salary, hourly_rate, first_value(salary) over (partition by dept_no order by salary desc) as max_salary, first_value(hourly_rate) over (partition by dept_no order by hourly_rate desc) as max_hourly_rate, first_value(salary) over (partition by dept_no order by salary desc) - salary as salary_gap, first_value(hourly_rate) over (partition by dept_no order by hourly_rate desc) - hourly_rate as hourly_rate_gap from employee; 

这样就可以得到类似如下的结果:

dept_no

emp_name

salary

hourly_rate

max_salary

max_hourly_rate

salary_gap

hourly_rate_gap

1

Alice

5000

50

5000

50

0

0

1

Bob

4000

40

5000

50

1000

10

… … … … … … … …

10.last_value()

last_value开窗函数是一种返回窗口框架,分区或结果集的最后一行的值的函数。last_value开窗函数的语法如下:

last_value(表达式) over ([partition by 分组列] [order by 排序列] [frame_clause]) 

这表示对分组列进行分组,然后按照排序列进行排序,最后返回每个分组内的最后一行的表达式的值。如果没有指定frame_clause,则默认为range between unbounded preceding and current row,即从分区开始到当前行。例如,假设有一个学生成绩表student_scores,有四个字段:学号studentId,数学成绩math,系别departmentId,班级classId。如果想要计算每个班级的数学成绩的最大值和最小值,并显示每个学生与之的差距,可以使用以下语句:

select studentId, math, departmentId, classId, last_value(math) over (partition by classId order by math) as max_math, first_value(math) over (partition by classId order by math) as min_math, last_value(math) over (partition by classId order by math) - math as math_gap from student_scores where departmentId = 'department1'; 

这样就可以得到类似如下的结果:

studentId

math

departmentId

classId

max_math

min_math

math_gap

111

69

department1

class1

94

69

25

113

74

department1

class1

94

69

20

… … … … … … …

11.nth_value()

nth_value开窗函数是一种返回窗口框架,分区或结果集中第N行的值的函数。nth_value开窗函数的语法如下:

nth_value(表达式, N) over ([partition by 分组列] [order by 排序列] [frame_clause]) 

这表示对分组列进行分组,然后按照排序列进行排序,最后返回每个分组内的第N行的表达式的值。如果没有指定frame_clause,则默认为range between unbounded preceding and current row,即从分区开始到当前行。例如,假设有一个学生成绩表student_scores,有四个字段:学号studentId,数学成绩math,系别departmentId,班级classId。如果想要计算每个班级的数学成绩的中位数和平均数,并显示每个学生与之的差距,可以使用以下语句:

select studentId, math, departmentId, classId, nth_value(math, count(*) over (partition by classId) / 2) over (partition by classId order by math) as median_math, avg(math) over (partition by classId) as avg_math, nth_value(math, count(*) over (partition by classId) / 2) over (partition by classId order by math) - math as median_gap, avg(math) over (partition by classId) - math as avg_gap from student_scores where departmentId = 'department1'; 

这样就可以得到类似如下的结果:

studentId

math

departmentId

classId

median_math

avg_math

median_gap

avg_gap

111

69

department1

class1

82

80.5

13

11.5

113

74

department1

class1

82

80.5

8

6.5

… … … … … … … …

12.lead()

lead开窗函数是一种允许你向前看多行并从当前行访问行的数据的函数。lead开窗函数的语法如下:

lead(表达式, N) over ([partition by 分组列] [order by 排序列]) 

这表示对分组列进行分组,然后按照排序列进行排序,最后返回每个分组内的当前行之后的第N行的表达式的值。如果没有指定N,则默认为1,即返回下一行的值。例如,假设有一个员工工资表employee_salaries,有三个字段:员工编号empId,姓名name,工资salary。如果想要计算每个员工与其下一个员工(按照工资降序排列)的工资差距,可以使用以下语句:

select empId, name, salary, lead(salary) over (order by salary desc) as next_salary, salary - lead(salary) over (order by salary desc) as salary_gap from employee_salaries; 

这样就可以得到类似如下的结果:

empId

name

salary

next_salary

salary_gap

101

Tom

10000

8000

2000

102

Bob

8000

7000

1000

… … … … …

13.lag()

lag开窗函数是一种允许你向后看多行并从当前行访问行的数据的函数。lag开窗函数的语法如下:

lag(表达式, N) over ([partition by 分组列] [order by 排序列]) 

这表示对分组列进行分组,然后按照排序列进行排序,最后返回每个分组内的当前行之前的第N行的表达式的值。如果没有指定N,则默认为1,即返回上一行的值。例如,假设有一个商品销售表product_sales,有四个字段:商品编号productId,商品名称productName,销售日期saleDate,销售数量saleQuantity。如果想要计算每个商品每天与前一天(按照日期升序排列)的销售数量差异,可以使用以下语句:

select productId, productName, saleDate, saleQuantity, lag(saleQuantity) over (partition by productId order by saleDate) as prev_quantity, saleQuantity - lag(saleQuantity) over (partition by productId order by saleDate) as quantity_diff from product_sales; 

这样就可以得到类似如下的结果:

productId

productName

saleDate

saleQuantity

prev_quantity

quantity_diff

1001

Apple

2023-01-01

50

NULL

NULL

1001

Apple

2023-01-02

60

50

10

… … … … … …

2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/16031.html

(0)
上一篇 2024年 9月 18日
下一篇 2024年 9月 18日

相关推荐

关注微信