📜  SQL 中的窗口函数(1)

📅  最后修改于: 2023-12-03 15:35:05.799000             🧑  作者: Mango

SQL中的窗口函数

在SQL中,窗口函数(Window Functions)是一种非常强大的功能,它可以让我们在查询结果中同时计算多个聚合值,甚至可以让我们进行高级计算。通过使用窗口函数,我们可以减少查询次数,提高查询效率,同时可以很容易地进行数据处理和分析。

窗口函数的语法

窗口函数可以用在SELECT、ORDER BY和HAVING子句中,并且需要在它们前面添加一个OVER子句来指定它们的窗口。OVER子句可以接受一组PARTITION BY或ORDER BY子句,来对结果进行分组或排序。

窗口函数的语法如下:

<window function> (<expression>) OVER (
    [PARTITION BY <expression> [, <expression> ... ]]
    [ORDER BY <expression> [ASC|DESC] [, <expression> [ASC|DESC] ... ]]
    [ROWS <frame specification>]
)

其中,<window function>是指要使用的窗口函数,<expression>是对窗口函数进行计算的列名或表达式。PARTITION BYORDER BY子句用来定义分组和排序方式。ROWS子句用来指定窗口的行范围。

常用的窗口函数
ROW_NUMBER()

ROW_NUMBER()函数用来计算一个分区中每行数据的行号。它不需要参数,用法如下:

SELECT ROW_NUMBER() OVER (ORDER BY <expression>) as row_number, <columns>
FROM <table>

其中,<expression>是指按照哪个列排序。<columns>是要查询的列名。

RANK()

RANK()函数用来计算每行数据在分区内的排名。它也不需要参数,用法和ROW_NUMBER()类似。不过,RANK()函数会把相同的行视为同一排名。

SELECT RANK() OVER (ORDER BY <expression>) as rank, <columns>
FROM <table>
DENSE_RANK()

DENSE_RANK()函数用来计算每行数据在分区内的密集排名。它和RANK()函数类似,不过DENSE_RANK()函数不会跳过相等的排名,而是直接生成连续的排名。

SELECT DENSE_RANK() OVER (ORDER BY <expression>) as dense_rank, <columns>
FROM <table>
NTILE()

NTILE(n)函数用来将分区分成n个等份,并返回当前行所在的等份。它的参数是要分成的份数。

SELECT NTILE(4) OVER (ORDER BY <expression>) as ntile, <columns>
FROM <table>
SUM(), AVG(), COUNT(), MAX()和MIN()

这些常用的聚合函数可以和OVER子句一起使用,来计算一个分区内的统计值。例如,以下查询将计算每个部门的总销售额,平均销售额和销售笔数:

SELECT department,
       SUM(amount) OVER (PARTITION BY department) as total_sales,
       AVG(amount) OVER (PARTITION BY department) as average_sales,
       COUNT(*) OVER (PARTITION BY department) as sales_count
FROM sales
窗口函数的行范围

除了以上介绍的窗口函数,还可以通过使用ROWS子句来指定窗口的行范围。ROWS子句可以指定当前行与相邻行之间的关系,从而控制计算结果。ROWS子句支持以下几种行范围:

UNBOUNDED PRECEDING

UNBOUNDED PRECEDING表示从第一行开始计算,到当前行为止的所有行。例如:

SUM(amount) OVER (ORDER BY date ROWS UNBOUNDED PRECEDING) as running_total

以上查询将计算从第一行到当前行为止的金额总和。

N PRECEDING

N PRECEDING表示从当前行往前数第N行,到当前行为止的所有行。例如:

AVG(amount) OVER (ORDER BY date ROWS 2 PRECEDING) as average_amount

以上查询将计算当前行及前面两行的平均金额。

BETWEEN N PRECEDING AND M FOLLOWING

BETWEEN N PRECEDING AND M FOLLOWING表示从当前行往前数第N行,到当前行往后数第M行的所有行。例如:

SUM(amount) OVER (ORDER BY date ROWS BETWEEN 3 PRECEDING AND 3 FOLLOWING) as sum_7days

以上查询将计算当前行以及前面3行和后面3行的金额总和。

UNBOUNDED FOLLOWING

UNBOUNDED FOLLOWING表示从当前行往后数到最后一行为止的所有行。例如:

MAX(amount) OVER (ORDER BY date ROWS UNBOUNDED FOLLOWING) as max_amount

以上查询将计算当前行到最后一行的最大金额。

总结

窗口函数是SQL中的一个非常强大的功能,可以让我们在查询结果中同时计算多个聚合值,并进行高级计算。除了以上介绍的ROW_NUMBER()、RANK()、DENSE_RANK()、NTILE()、SUM()、AVG()、COUNT()、MAX()和MIN()函数之外,还有更多的窗口函数可供使用。不过,在使用窗口函数时需要注意,要根据具体的业务需求选择适当的窗口函数和行范围,以保证计算结果的准确性。