这篇文章主要介绍了MySQL窗口函数及其在解决分析查询挑战中的实用应用。MySQL从8.0版本开始支持窗口函数,这些函数使你能够以新的、更简单的方式解决查询问题,并提供更好的性能。
假设我们有一个销售表,它存储了员工和财年的销售情况:
CREATE TABLE sales(
sales_employee VARCHAR(50) NOT NULL,
fiscal_year INT NOT NULL,
sale DECIMAL(14,2) NOT NULL,
PRIMARY KEY(sales_employee,fiscal_year)
);
INSERT INTO sales(sales_employee,fiscal_year,sale)
VALUES('Bob',2016,100),
('Bob',2017,150),
('Bob',2018,200),
('Alice',2016,150),
('Alice',2017,100),
('Alice',2018,200),
('John',2016,200),
('John',2017,150),
('John',2018,250);
SELECT * FROM sales;
理解窗口函数的一个好方法是从聚合函数开始。聚合函数将多行数据汇总为单个结果行。例如,以下SUM()函数返回所有员工在记录年份的总销售额:
SELECT
SUM(sale)
FROM
sales;
GROUP BY子句允许你将聚合函数应用于一部分行。例如,你可能想计算财年的总销售额:
SELECT
fiscal_year,
SUM(sale)
FROM
sales
GROUP BY
fiscal_year;
在这两个例子中,聚合函数都减少了查询返回的行数。
像带有GROUP BY子句的聚合函数一样,窗口函数也对一部分行进行操作,但它们不会减少查询返回的行数。
例如,以下查询返回每个员工的销售额,以及员工按财年的总销售额:
SELECT
fiscal_year,
sales_employee,
sale,
SUM(sale) OVER (PARTITION BY fiscal_year) total_sales
FROM
sales;
在这个例子中,SUM()函数作为一个窗口函数,操作由OVER子句内容定义的一组行。SUM()函数应用的一组行被称为窗口。
SUM()窗口函数不仅报告了按财年的总销售额(就像在带有GROUP BY子句的查询中那样),而且还在每一行中报告了结果,而不是返回的总行数。
注意,窗口函数是在所有JOIN、WHERE、GROUP BY和HAVING子句之后,以及在ORDER BY、LIMIT和SELECT DISTINCT之前执行的。
窗口函数的语法如下:
window_function_name(expression) OVER (
[partition_defintion]
[order_definition]
[frame_definition]
)
在这个语法中:
首先,指定窗口函数名称,后面跟着一个表达式。
其次,指定OVER子句,它有三个可能的元素:分区定义、排序定义和帧定义。
在OVER子句后面的开括号和闭括号是必需的,即使没有表达式,例如:
window_function_name(expression) OVER()
在本教程中,你已经了解了MySQL窗口函数及其语法。