SQL中的开窗函数

SQL Server的开窗函数

开窗函数是一种用于处理查询结果的强大工具。它们可以在查询结果集中创建子集,然后对这些子集执行聚合、排序、排名等操作,而不会影响原始查询结果的顺序、分组或过滤。开窗函数通常需要使用 OVER 子句来指定窗口(Window)的大小和位置,以及排序规则。
使用开窗函数可以轻松实现许多复杂的查询需求,如计算行、列、分组的总计、累计、平均值、移动平均值、排名等,同时也可以提高查询效率和灵活性。对于SQL Server的开发和数据分析工作来说,掌握开窗函数是非常重要的一项技能。

开窗函数=聚合函数(SUM/COUNT/MAX/MIN/AVG/LAG……)+OVER子句
开窗函数中的OVER子句OVER子句是开窗函数的核心,用于定义窗口(Window)的大小和位置,以及排序规则。OVER子句的语法如下:

OVER (
  [PARTITION BY partition_expression, ... ]
  [ORDER BY order_expression [ASC | DESC], ... ]
  [ROWS { UNBOUNDED PRECEDING | n PRECEDING | CURRENT ROW | n FOLLOWING | UNBOUNDED FOLLOWING }]
)

其中,各个参数的含义如下:
PARTITION BY:指定分区表达式,将查询结果分成不同的分区,每个分区内部进行开窗函数的计算。如果省略该参数,则整个查询结果集被视为一个分区。
ORDER BY:指定排序表达式和排序规则,用于对每个分区内的数据进行排序。如果省略该参数,则不保证分区内的数据顺序。
ROWS:指定行范围,用于确定每个分区内要计算的行。常见的行范围有以下几种:

UNBOUNDED PRECEDING:从分区的第一行开始计算。
n PRECEDING:从当前行往前数n行开始计算。
CURRENT ROW:仅计算当前行。
n FOLLOWING:从当前行往后数n行开始计算。
UNBOUNDED FOLLOWING:计算到分区的最后一行。

OVER子句的使用方法如下:

SELECT 
  column1,
  column2,
  ...,
  aggregate_function(column3) OVER (
    [PARTITIONBY partition_expression, ... ]
    [ORDERBY order_expression [ASC | DESC], ... ]
    [ROWS { UNBOUNDED PRECEDING | n PRECEDING | CURRENT ROW | n FOLLOWING | UNBOUNDED FOLLOWING }]
  ) AS resultFROM table_name;

其中,aggregate_function为聚合函数(如SUM、AVG、COUNT、MAX、MIN、ROW_NUMBER、LAG等),column1、column2、column3为查询结果集中的列名。使用OVER子句后,聚合函数将会对每个分区内的数据进行计算,并将计算结果作为新的列(result)添加到查询结果集中。

一个例子,一个业务表,有字段客户名、操作部门和业务量,一个客户会有多个操作部门,每个操作部门不同的业务量,同一个客户的有些部门的业务量可能相同,现在想取出每个客户唯一的操作部门,按照操作部门业务量最多的选取,业务量相同的话取排在最前面的部门。

select * from (
select 客户名称,终端所属片区,单量,ROW_NUMBER() over(partition by 客户名称 order by 单量 DESC) as rn FROM (
select 客户名称,终端所属片区,SUM(揽件单量) as '单量'  from dbo.[快递快运明细]
group by 客户名称,终端所属片区
) a
) b
where rn=1  --取排序为1的部门

OVER()子句中的ROWS参数ROWS参数是OVER子句中用于定义窗口范围的一个重要参数,它决定了开窗函数计算时所考虑的行的范围,熟练使用可以达成意想不到的效果。

UNBOUNDED PRECEDING
UNBOUNDED PRECEDING表示从分区的第一行开始计算,直到当前行。例如:

SELECT 
  column1,
  column2,
  SUM(column3) OVER (
    ORDERBY column1
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  ) AS result FROM table_name;

以上代码将对每个分区内的数据进行排序,并计算每个分区内的累计和。ROWS参数为UNBOUNDED PRECEDING和CURRENT ROW,表示计算从分区的第一行到当前行的累计和。

n PRECEDING
n PRECEDING表示从当前行往前数n行开始计算,直到当前行。例如:

SELECT 
  column1,
  column2,
  AVG(column3) OVER (
    ORDERBY column1
    ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
  ) AS result FROM table_name;

以上代码将对每个分区内的数据进行排序,并计算每个分区内的移动平均值。ROWS参数为2 PRECEDING和
CURRENT ROW,表示计算当前行和前两行的平均值。
CURRENT ROWCURRENT ROW表示仅计算当前行。例如:

SELECT 
  column1,
  column2,
  column3,
  MAX(column3) OVER (
    ORDERBY column1
    ROWS BETWEEN CURRENTROW AND UNBOUNDED FOLLOWING
  ) AS result FROM table_name;

以上代码将对每个分区内的数据进行排序,并计算每个分区内的最大值。ROWS参数为CURRENT ROW和UNBOUNDED FOLLOWING,表示计算当前行和后面所有行的最大值。
n FOLLOWINGn FOLLOWING表示从当前行往后数n行开始计算,直到分区的最后一行。例如:

SELECT 
  column1,
  column2,
  SUM(column3) OVER (
    ORDERBY column1
    ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING
  ) AS result FROM table_name;

以上代码将对每个分区内的数据进行排序,并计算每个分区内的滚动总和。ROWS参数为CURRENT ROW和2 FOLLOWING,表示计算当前行和后面两行的总和。
UNBOUNDED FOLLOWINGUNBOUNDED FOLLOWING表示计算到分区的最后一行。例如:

SELECT 
  column1,
  column2,
  SUM(column3) OVER (
    ORDERBY column1
    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
  ) AS result FROM table_name;

以上代码将对每个分区内的数据进行排序,并计算每个分区内的后面所有行的累计和。ROWS参数为CURRENT ROW和UNBOUNDED FOLLOWING,表示计算当前行和后面所有行的累计和。

行之间的计算-LAG()函数LAG函数是SQL Server中的一种开窗函数,用于获取当前行前n行的数据。LAG函数通常用于计算当前行与前一行之间的差值、增长率、趋势等,或者用于计算当前行与前一行,还可以应用于求解连续类问题等。LAG函数的基础语法如下:

LAG (value_expression [, offset] [, default]) 
    OVER (
        [PARTITIONBY partition_expression, ... ] 
        ORDERBY sort_expression [ASC|DESC], ...
    )

其中,value_expression为需要获取的列名或表达式,offset为要向前获取的行数(默认为1),default为当获取的行不存在时返回的默认值(默认为NULL)。
示例:
使用开窗函数LAG计算1-10月业务量月环比

SELECT 
    t1.month, 
    t1.sales_volume, 
    LAG(t1.sales_volume, 1) OVER (ORDER BY t1.month) AS last_month_sales_volume,
    (t1.sales_volume - LAG(t1.sales_volume, 1) OVER (ORDER BY t1.month)) / LAG(t1.sales_volume, 1) OVER (ORDER BY t1.month) AS month_on_month_growth_rate
FROM 
    sales t1
WHERE 
    t1.month BETWEEN '2021-01' AND '2021-10'
ORDER BY 
    t1.month

猜你喜欢

转载自blog.csdn.net/qq_33909788/article/details/131886543
今日推荐