跳到主要内容

index

已理解您的要求,我将严格按照您提供的规则进行翻译。请提供需要翻译的Markdown或JSON内容,我会立即开始翻译工作。


title: '窗口函数'

概述

窗口函数对一组相关的行(“窗口”)进行操作。

对于每个输入行,窗口函数返回一个输出行,该输出行取决于传递给函数的特定行以及窗口中其他行的值。

主要有两种类型的顺序敏感窗口函数:

  • 排名相关函数:排名相关函数根据行的“排名”列出信息。例如,按每年利润降序排列商店,利润最高的商店将排名为1,利润第二高的商店将排名为2,依此类推。

  • 窗口框架函数:窗口框架函数允许您在窗口中的行子集上执行滚动操作,例如计算累计总和或移动平均值。

支持窗口的函数列表

下表列出了所有窗口函数。

函数名称类别窗口窗口框架备注
ARRAY_AGG通用
AVG通用
AVG_IF通用
COUNT通用
COUNT_IF通用
COVAR_POP通用
COVAR_SAMP通用
MAX通用
MAX_IF通用
MIN通用
MIN_IF通用
STDDEV_POP通用
STDDEV_SAMP通用
MEDIAN通用
QUANTILE_CONT通用
QUANTILE_DISC通用
KURTOSIS通用
SKEWNESS通用
SUM通用
SUM_IF通用
CUME_DIST排名相关
PERCENT_RANK排名相关
DENSE_RANK排名相关
RANK排名相关
ROW_NUMBER排名相关
NTILE排名相关
FIRST_VALUE排名相关
FIRST排名相关
LAST_VALUE排名相关
LAST排名相关
NTH_VALUE排名相关
LEAD排名相关
LAG排名相关

窗口语法

<function> ( [ <arguments> ] ) OVER ( { named window | inline window } )

named window ::=
{ window_name | ( window_name ) }

inline window ::=
[ PARTITION BY <expression_list> ]
[ ORDER BY <expression_list> ]
[ window frame ]

named window 是在 SELECT 语句的 WINDOW 子句中定义的窗口,例如:SELECT a, SUM(a) OVER w FROM t WINDOW w AS ( inline window )

<function> 是(聚合函数、排名函数、值函数)之一。

OVER 子句指定该函数用作窗口函数。

PARTITION BY 子句允许将行分组为子组,例如按城市、按年份等。PARTITION BY 子句是可选的。您可以在不将整个行组分解为子组的情况下进行分析。

ORDER BY 子句对窗口内的行进行排序。

window frame 子句指定窗口框架类型和窗口框架范围。window frame 子句是可选的。如果省略 window frame 子句,默认的窗口框架类型为 RANGE,默认的窗口框架范围为 UNBOUNDED PRECEDING AND CURRENT ROW

窗口框架语法

window frame 可以是以下类型之一:

cumulativeFrame ::=
{
{ ROWS | RANGE } BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
| { ROWS | RANGE } BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
}
slidingFrame ::=
{
ROWS BETWEEN <N> { PRECEDING | FOLLOWING } AND <N> { PRECEDING | FOLLOWING }
| ROWS BETWEEN UNBOUNDED PRECEDING AND <N> { PRECEDING | FOLLOWING }
| ROWS BETWEEN <N> { PRECEDING | FOLLOWING } AND UNBOUNDED FOLLOWING
}

示例

创建表

CREATE TABLE employees (
employee_id INT,
first_name VARCHAR,
last_name VARCHAR,
department VARCHAR,
salary INT
);

插入数据

INSERT INTO employees (employee_id, first_name, last_name, department, salary) VALUES
(1, 'John', 'Doe', 'IT', 75000),
(2, 'Jane', 'Smith', 'HR', 85000),
(3, 'Mike', 'Johnson', 'IT', 90000),
(4, 'Sara', 'Williams', 'Sales', 60000),
(5, 'Tom', 'Brown', 'HR', 82000),
(6, 'Ava', 'Davis', 'Sales', 62000),
(7, 'Olivia', 'Taylor', 'IT', 72000),
(8, 'Emily', 'Anderson', 'HR', 77000),
(9, 'Sophia', 'Lee', 'Sales', 58000),
(10, 'Ella', 'Thomas', 'IT', 67000);

示例 1:按工资对员工进行排名

在此示例中,我们使用 RANK() 函数按工资降序对员工进行排名。工资最高的员工将获得排名1,工资最低的员工将获得最高的排名号。

SELECT employee_id, first_name, last_name, department, salary, RANK() OVER (ORDER BY salary DESC) AS rank
FROM employees;

结果:

employee_idfirst_namelast_namedepartmentsalaryrank
3MikeJohnsonIT900001
2JaneSmithHR850002
5TomBrownHR820003
8EmilyAndersonHR770004
1JohnDoeIT750005
7OliviaTaylorIT720006
10EllaThomasIT670007
6AvaDavisSales620008
4SaraWilliamsSales600009
9SophiaLeeSales5800010

示例 2:计算每个部门的总工资

在此示例中,我们使用 SUM() 函数与 PARTITION BY 来计算每个部门的总工资。每行将显示部门及其总工资。

SELECT department, SUM(salary) OVER (PARTITION BY department) AS total_salary
FROM employees;

结果:

departmenttotal_salary
HR244000
HR244000
HR244000
IT304000
IT304000
IT304000
IT304000
Sales180000
Sales180000
Sales180000

示例 3:计算每个部门的工资累计总和

在此示例中,我们使用 SUM() 函数与累积窗口框架来计算每个部门内的工资累计总和。累计总和基于按 employee_id 排序的员工的工资。

SELECT employee_id, first_name, last_name, department, salary, 
SUM(salary) OVER (PARTITION BY department ORDER BY employee_id
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total
FROM employees;

结果:

employee_idfirst_namelast_namedepartmentsalaryrunning_total
2JaneSmithHR8500085000
5TomBrownHR82000167000
8EmilyAndersonHR77000244000
1JohnDoeIT7500075000
3MikeJohnsonIT90000165000
7OliviaTaylorIT72000237000
10EllaThomasIT67000304000
4SaraWilliamsSales6000060000
6AvaDavisSales62000122000
9SophiaLeeSales58000180000
开始使用 Databend Cloud
低成本
快速分析
多种数据源
弹性扩展
注册