SQL窗口函数是SQL中的一种高级函数,它允许用户在不显式分组查询的情况下对结果集进行分组和聚合计算。窗口函数的特别之处在于,它们将结果集中的每一行看作一个单独的计算对象,而不是将结果集划分为分组并计算每个分组的聚合值。这就使得窗口函数能够为结果集中的每一行计算类似排名、行号、百分比和移动聚合函数等值。
SQL窗口函数的语法如下:
(资料图片仅供参考)
<窗口函数> OVER ([PARTITION BY <分组列> [, <分组列>...]] [ORDER BY <排序列> [ASC | DESC] [, <排序列> [ASC | DESC]]...] [])
其中:
<窗口函数>
: 定义要在窗口中计算的聚合函数或其它分析函数,如COUNT、RANK、SUM等。OVER
: 窗口函数的核心关键字。PARTITION BY
: 定义要用来分组的一组列名。ORDER BY
: 定义用来排序的一组列名。
: 定义窗口的行集合。默认为 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
,表示窗口包括从窗口开始到当前行的所有行。下面的例子说明了如何使用窗口函数计算每个部门的平均工资,并根据平均工资进行排名。
SELECT department, employee_name, salary, AVG(salary) OVER (PARTITION BY department) average_salary, RANK() OVER (PARTITION BY department ORDER BY salary DESC) salary_rankFROM employee;
在这个例子中,PARTITION BY定义了用于分组计算平均工资的列名,OVER后面依次定义了需要计算的列名和相应的窗口函数。 AVG(salary) OVER (PARTITION BY department)
的意思是对于每个部门,计算 salary
列的平均值,而 RANK() OVER (PARTITION BY department ORDER BY salary DESC)
的意思是计算每个部门中 salary
列的排名。SQL窗口函数的语法和用法比较复杂,但它极大地拓展了SQL查询的能力,使得更多复杂的查询可以得以实现。
窗口函数是一种SQL函数,可以在不影响查询结果的情况下,为查询结果集中的每一行计算聚合函数、排名、行号等。
窗口函数的使用场景有很多,例如统计某个时间段内的每天销售量排名、计算每个部门的平均工资并与其他部门进行比较、计算每个产品上个月和本月的销售额变化等。
以下是一个使用窗口函数的查询示例和结果,该查询用于计算某个时间段内每天的销售量排名。
假设有一张包含销售信息的表sales,包括销售日期、销售量和产品ID等字段。
现在需要查询2021年1月1日至1月10日期间每天的销售量排名,包括每天的日期和排名信息。
以下是使用窗口函数实现该查询的SQL语句:
SELECT sale_date, sale_volume, ROW_NUMBER() OVER(PARTITION BY sale_date ORDER BY sale_volume DESC) as sales_rankFROM salesWHERE sale_date BETWEEN "2021-01-01" AND "2021-01-10"
该查询将sales表根据销售日期进行分组,计算每个日期的销售量,并使用ROW_NUMBER()函数为每个日期的销售量进行排名。
以下是该查询的查询结果:
sale_date | sale_volume | sales_rank |
---|---|---|
2021-01-01 | 12500 | 1 |
2021-01-02 | 13800 | 1 |
2021-01-03 | 13000 | 1 |
2021-01-04 | 11800 | 2 |
2021-01-05 | 12500 | 1 |
2021-01-06 | 14000 | 1 |
2021-01-07 | 11500 | 1 |
2021-01-08 | 12800 | 1 |
2021-01-09 | 13100 | 1 |
2021-01-10 | 12900 | 1 |
ps:上面的结果有问题。
SQL的窗口函数中常见的排序方法包括以下几种:
注意,以上窗口函数中的排序方法都是基于ORDER BY子句中指定的列或表达式的排序。
以下是五种窗口函数的排序方法及其例子:
SELECT ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num, employee_name, salaryFROM employee;
该语句会对employee表按照salary字段降序排序,并为每行分配一个不重复的行号存储在row_num字段中。
SELECT RANK() OVER (ORDER BY total_sales DESC) AS ranking, region_name, total_salesFROM sales_summaryWHERE year = "2021";
该语句会对2021年销售总额按照降序排序,并为每行分配一个排名存储在ranking字段中。
SELECT DENSE_RANK() OVER (ORDER BY exam_score DESC) AS rank, student_name, exam_scoreFROM exam_resultsWHERE exam_type = "final";
该语句会对final考试的成绩按照降序排序,并为每行分配一个密集排名存储在rank字段中。
SELECT NTILE(4) OVER (ORDER BY product_sales DESC) AS quartile, product_name, product_salesFROM product_summaryWHERE year = "2021";
该语句会将2021年产品销售额按照降序排序,并将其分成四个桶,为每行分配一个桶号存储在quartile字段中。
SELECT employee_name, salary, LAG(salary, 1) OVER (ORDER BY salary) AS prev_salary, LEAD(salary, 1) OVER (ORDER BY salary) AS next_salaryFROM employee;
该语句会对employee表按照salary字段排序,并为每行获取前一行和后一行的salary值存储在prev_salary和next_salary字段中。
窗口函数是在SELECT语句中用来执行聚合、排序、排名等操作的一种特殊函数。它们操作一个窗口(Window)内的数据集,并返回一个与当前行相关的聚合结果。
以下是一些使用窗口函数的常见场景和示例:
SELECT order_no, order_date, customer_name, order_amount, RANK() OVER (ORDER BY order_amount DESC) as rank FROM orders;
SELECT customer_name, order_date, order_amount, SUM(order_amount) OVER (PARTITION BY customer_name ORDER BY order_date) as cumulative_sales FROM orders;
SELECT order_no, order_date, order_amount, order_amount - LAG(order_amount, 1, 0) OVER (ORDER BY order_date) as sales_increase FROM orders;
假设有一张包含学生成绩信息的表scores,包括学生ID,课程ID和成绩。现在需要查询每个学生最高成绩和次高成绩,并计算两者的差值(用作成绩提升分析)。
以下是使用窗口函数实现该查询的SQL语句:
SELECT student_id, MAX(score) as max_score, LAG(MAX(score), 1, 0) OVER (PARTITION BY student_id ORDER BY score DESC) as second_max_score, MAX(score) - LAG(MAX(score), 1, 0) OVER (PARTITION BY student_id ORDER BY score DESC) as score_gapFROM scoresGROUP BY student_id
该查询将scores表按照student_id分组,计算每个学生的最高成绩和次高成绩,并计算两者的差值。以下是该查询的查询结果:
student_id | max_score | second_max_score | score_gap |
---|---|---|---|
1 | 95 | 89 | 6 |
2 | 88 | 82 | 6 |
3 | 86 | 75 | 11 |
4 | 92 | 84 | 8 |
5 | 94 | 91 | 3 |
以上是用markdown展示的查询结果,包括查询到的学生ID,最高成绩,次高成绩和两者的差值。
SELECT order_date, order_amount, AVG(order_amount) OVER (ORDER BY order_date ROWS BETWEEN 13 PRECEDING AND CURRENT ROW) as moving_average FROM orders;
这些只是窗口函数的一些常见用途和示例。实际上,窗口函数非常灵活,可以用于各种不同的数据分析和处理场景。
X 关闭
Copyright © 2015-2022 大众服装网版权所有 备案号:豫ICP备20014643号-14 联系邮箱: 905 14 41 07@qq.com