10 窗口函数

SQL 窗口函数(Window Functions)是一种在查询结果集的特定窗口(行集)上进行计算的函数

它为每行数据提供了一个聚合值,而不需要像传统聚合函数那样将多行数据合并为一行,在不影响原表行数的情况下,进行各种统计分析。

一、语法结构

<窗口函数> OVER (
    [PARTITION BY <列名1>[, <列名2> ...]]
    [ORDER BY <列名1> [ASC|DESC][, <列名2> [ASC|DESC] ...]]
    [窗口子句]
)
  • 窗口函数

    • 常见的有聚合函数(如 SUMAVGCOUNT 等)
    • 排名函数(如 RANKDENSE_RANKROW_NUMBER 等)
    • 分析函数(如 LEADLAG 等)
  • PARTITION BY 子句:可选,用于将结果集划分为多个分区窗口函数会在每个分区内独立计算。类似于 GROUP BY,但不会像 GROUP BY 那样合并行。

  • ORDER BY 子句:可选,用于指定分区内的排序规则,决定了窗口函数处理行的顺序。

  • 窗口子句:可选,进一步定义窗口的范围,例如指定当前行前后的行作为窗口范围。


二、常见窗口函数类型及示例

1. 聚合窗口函数

用于在窗口内进行聚合计算,如求和、求平均值等。

-- 假设存在一个 sales 表,包含 product_id、sale_date 和 amount 字段
SELECT 
    product_id,
    sale_date,
    amount,
    SUM(amount) OVER (PARTITION BY product_id ORDER BY sale_date) AS cumulative_amount
FROM 
    sales;

在上述示例中,SUM(amount) OVER (PARTITION BY product_id ORDER BY sale_date) 会为每个产品(按 product_id 分区)计算截至当前销售日期的累计销售金额。

2. 排名窗口函数

用于为结果集中的行进行排名。

  • ROW_NUMBER()为每行分配一个唯一的连续整数,从 1 开始,按照 ORDER BY 子句指定的顺序排列。
SELECT 
    employee_id,
    salary,
    ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num
FROM 
    employees;

此示例会为 employees 表中的每行按照薪资降序分配一个唯一的行号。

  • RANK():排名函数,如果有相同的值,会赋予相同的排名下一个排名会跳过相应的数字。
SELECT 
    employee_id,
    salary,
    RANK() OVER (ORDER BY salary DESC) AS rank_num
FROM 
    employees;

若有两个员工薪资相同且排名为第 2,则下一个员工的排名为第 4。

  • DENSE_RANK():也是排名函数,但即使有相同的值,下一个排名也不会跳过,是连续的。
SELECT 
    employee_id,
    salary,
    DENSE_RANK() OVER (ORDER BY salary DESC) AS dense_rank_num
FROM 
    employees;

若有两个员工薪资相同且排名为第 2,则下一个员工的排名为第 3。

3. 分析窗口函数

用于获取当前行前后的行的数据。

  • LAG():用于获取当前行之前某一行的值
SELECT 
    sale_date,
    amount,
    LAG(amount, 1) OVER (ORDER BY sale_date) AS previous_amount
FROM 
    sales;

此示例会获取每行销售金额的前一行销售金额。

  • LEAD():用于获取当前行之后某一行的值。
SELECT 
    sale_date,
    amount,
    LEAD(amount, 1) OVER (ORDER BY sale_date) AS next_amount
FROM 
    sales;

该示例会获取每行销售金额的后一行销售金额。


三、窗口函数的优势

  • 灵活性:可以在不使用复杂的子查询或连接的情况下,在同一查询中进行多种计算。
  • 性能优化:在处理大数据集时,窗口函数通常比子查询更高效。
  • 可读性:使 SQL 查询更简洁易读,尤其是在需要进行复杂分析时。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值