函数名(参数) OVER (PARTITION BY子句 ORDER BY子句 ROWS/RANGE子句)
由三部分组成: 函数名:如sum、max、min、count、avg等聚合函数以及lead、lag行比较函数等; over:
关键字,表示前面的函数是分析函数,不是普通的集合函数; 分组子句:over关键字后面挂号内的内容;
分析子句又由下面三部分组成: PARTITION BY :分组子句,表示分析函数的计算范围,不同的组互不相干; ORDER BY:
排序子句,表示分组后,组内的排序方式; ROWS/RANGE:窗口子句,是在分组(PARTITION
BY)后,组内的子分组(也称窗口),此时分析函数的计算范围窗口,而不是PARTITON。窗口有两种,ROWS和RANGE;
PARTITION BY 子句:
PARTITION BY
来指定部门。ORDER BY 子句:
ROWS/RANGE 子句:
ROWS
:指定一个明确的行数范围。例如,你可以指定从当前行开始并包括之前的5行。RANGE
:基于列值来定义范围。例如,你可以指定从当前行开始并包括到相同列值的最后一行。开窗函数中的ROWS和RANGE子句用于定义窗口的范围,即函数将在哪些行上执行计算。这两个子句有一些关键的区别:
ROWS子句:
RANGE子句:
总结:
以下详细的描述并且准确地解释了SQL中开窗函数中的ROWS和RANGE子句及其用法。
1. current row:当前行。
2. unbounded:表示无限的范围,例如在排序中表示从最前面或最后面的记录开始。
3. unbounded preceding:表示区间的第一行,通常与聚合函数一起使用,如计算总和或平均值。
4. unbounded following:表示区间的最后一行,常用于分组的结尾部分。
5. unbounded preceding and unbounded following:针对当前所有记录的前一条、后一条记录,分组中的所有记录。
6. preceding:在之前的行,n preceding:当前行之前的n行。
7. following:在之后的行,n following:当前行之后的n行。
8. rows between:用于定义一个明确的行数范围,如“rows between unbounded preceding and current row”表示从第一行到当前行的数据。
9. range between:基于列值的范围,如“range between current row and 350 following”表示从当前行到当前行数据+350的范围内的数据。
10. range between preceding and following:定义一个基于列值的动态范围,如“range between 5 preceding and 5 following”表示当前行数据幅度减5加5后的范围内的数据。
以下是一些实际性的案例,展示了如何使用开窗函数的ROWS和RANGE子句:
假设有一个名为"employees"的表,其中包含员工的信息和工资。现在要计算每个部门的员工工资总额。
SELECT department, |
|
name, |
|
salary, |
|
SUM(salary) OVER (PARTITION BY department) as total_salary |
|
FROM employees; |
在这个例子中,我们使用PARTITION BY子句将数据分成不同的部门,然后使用SUM函数计算每个部门的员工工资总额。通过将SUM函数与OVER子句结合使用,我们可以轻松地计算每个部门的工资总额。
2. 案例二:计算每个员工的累计销售额
假设有一个名为"sales"的表,其中包含销售数据和销售人员的名字。现在要计算每个销售人员的累计销售额。
SELECT name, |
|
sale_date, |
|
sale_amount, |
|
SUM(sale_amount) OVER (PARTITION BY name ORDER BY sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as cumulative_sales |
|
FROM sales; |
在这个例子中,我们使用PARTITION BY子句按销售人员名字分组数据,并使用ORDER BY子句按销售日期排序。然后,我们使用SUM函数计算每个销售人员的累计销售额,通过指定ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW来定义窗口范围,包括从第一行到当前行的所有行。
3. 案例三:计算每个员工的销售排名
假设有一个名为"sales"的表,其中包含销售数据和销售人员的名字。现在要计算每个销售人员的销售排名。
SELECT name, |
|
sale_amount, |
|
RANK() OVER (ORDER BY sale_amount DESC) as sales_rank |
|
FROM sales; |
在这个例子中,我们使用RANK函数计算每个销售人员的销售排名。通过指定ORDER BY子句按销售金额降序排序,RANK函数将为每个销售人员分配一个排名值。使用OVER子句定义窗口范围,以便RANK函数在整个结果集上执行计算。