一篇文章看懂SQL中的开窗函数

SQL开窗函数是用于处理分组内计算的特殊函数,能在不破坏原有数据结构的情况下进行复杂分析。本文助你快速理解并掌握开窗函数的使用。

深入浅出,一文掌握SQL中的开窗函数

在SQL查询中,我们经常需要对数据进行分组、排序以及计算各种聚合值,而开窗函数(Window Function)为我们提供了一种强大的方法来处理这类需求,开窗函数可以在不破坏原有数据行结构的情况下,对数据进行分组、排序、计算聚合值等操作,本文将详细介绍开窗函数的概念、用法以及在实际场景中的应用。

一篇文章看懂SQL中的开窗函数

开窗函数的基本概念

1、什么是开窗函数?

开窗函数是一种特殊的函数,它可以在一组行(称为“窗口”)上执行计算,同时保留原始行的结构,这意味着开窗函数不会像普通聚合函数(如SUM、AVG等)那样将多行数据聚合成一行,而是在每行数据上单独进行计算。

2、开窗函数的组成

开窗函数通常由两部分组成:函数部分和开窗部分。

(1)函数部分:可以是SQL内置的聚合函数(如SUM、AVG、MAX等),也可以是自定义的标量函数。

(2)开窗部分:用于定义窗口的范围和排序规则,主要包括以下三个要素:

- 分区(PARTITION BY):将数据行按照某个或多个列进行分组。

- 排序(ORDER BY):指定窗口内数据的排序规则。

- 窗口帧(FRAME):定义窗口的边界,即计算的范围。

开窗函数的分类与用法

1、聚合开窗函数

聚合开窗函数主要包括SUM、AVG、MAX、MIN等,它们可以在窗口内对数据进行聚合计算。

示例:计算每个部门内员工的平均薪资。

SELECT
  department_id,
  employee_id,
  salary,
  AVG(salary) OVER (PARTITION BY department_id) AS avg_salary
FROM
  employees;

2、排序开窗函数

一篇文章看懂SQL中的开窗函数

排序开窗函数主要包括ROW_NUMBER、RANK、DENSE_RANK等,它们可以在窗口内对数据进行排序。

(1)ROW_NUMBER:为窗口内的每一行分配一个唯一的序号。

示例:为每个部门内的员工按薪资升序分配序号。

SELECT
  department_id,
  employee_id,
  salary,
  ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary ASC) AS rn
FROM
  employees;

(2)RANK:为窗口内的每一行分配一个序号,但存在并列情况时,序号会跳过。

示例:为每个部门内的员工按薪资升序分配序号,并列情况跳过。

SELECT
  department_id,
  employee_id,
  salary,
  RANK() OVER (PARTITION BY department_id ORDER BY salary ASC) AS rk
FROM
  employees;

(3)DENSE_RANK:为窗口内的每一行分配一个序号,但存在并列情况时,序号不会跳过。

示例:为每个部门内的员工按薪资升序分配序号,并列情况不跳过。

SELECT
  department_id,
  employee_id,
  salary,
  DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary ASC) AS dr
FROM
  employees;

3、偏移开窗函数

偏移开窗函数主要包括LAG、LEAD等,它们可以访问窗口内当前行之前或之后的行。

(1)LAG:获取窗口内当前行之前指定偏移量的行的数据。

示例:获取每个部门内员工的上一条记录的薪资。

SELECT
  department_id,
  employee_id,
  salary,
  LAG(salary, 1) OVER (PARTITION BY department_id ORDER BY salary ASC) AS prev_salary
FROM
  employees;

(2)LEAD:获取窗口内当前行之后指定偏移量的行的数据。

示例:获取每个部门内员工的下一条记录的薪资。

一篇文章看懂SQL中的开窗函数

SELECT
  department_id,
  employee_id,
  salary,
  LEAD(salary, 1) OVER (PARTITION BY department_id ORDER BY salary ASC) AS next_salary
FROM
  employees;

开窗函数在实际场景中的应用

1、首尾记录查询

使用开窗函数可以轻松查询每个分组的首条或最后一条记录。

示例:查询每个部门薪资最高和最低的员工。

SELECT
  department_id,
  employee_id,
  salary,
  RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS max_salary_rank,
  RANK() OVER (PARTITION BY department_id ORDER BY salary ASC) AS min_salary_rank
FROM
  employees
WHERE
  max_salary_rank = 1 OR min_salary_rank = 1;

2、动态分组

开窗函数可以用于动态创建分组,以便于进行进一步的分析。

示例:根据员工薪资水平动态创建分组。

WITH salary_groups AS (
  SELECT
    employee_id,
    salary,
    DENSE_RANK() OVER (ORDER BY salary DESC) AS salary_group
  FROM
    employees
)
SELECT
  salary_group,
  AVG(salary) AS avg_salary
FROM
  salary_groups
GROUP BY
  salary_group;

3、连续登录天数

使用开窗函数可以计算用户连续登录的天数。

示例:计算每个用户连续登录的天数。

SELECT
  user_id,
  login_date,
  DATE_SUB(login_date, INTERVAL ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date ASC) DAY) AS start_date,
  ROW_NUMBER() OVER (PARTITION BY user_id, DATE_SUB(login_date, INTERVAL ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date ASC) DAY) ORDER BY login_date ASC) AS consecutive_days
FROM
  user_logins;

开窗函数是SQL查询中一种非常强大的功能,它可以在不破坏原始数据行结构的情况下,对数据进行分组、排序、计算聚合值等操作,通过掌握开窗函数的用法,我们可以轻松应对各种复杂的查询需求,在实际工作中,灵活运用开窗函数可以提高查询效率,帮助我们更好地分析数据。

原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/322719.html

Like (0)
Donate 微信扫一扫 微信扫一扫
K-seo的头像K-seoSEO优化员
Previous 2024-02-18 18:49
Next 2024-02-18 18:50

相关推荐

  • kafka的负载均衡怎么实现

    Kafka的负载均衡是通过分区的方式将消息进行分散处理,消费者可以并行消费不同的分区,从而实现负载均衡。当消费者组内新增或减少消费者时,Kafka会自动进行负载均衡,重新分配每个消费者所消费的分区,保证每个消费者消费的分区数量基本相同,从而实现消费者之间的负载均衡 。

    2024-01-22
    0248
  • sql怎么自动获取当前日期和时间

    您可以使用SQL中的GETDATE()函数获取当前日期和时间,或者使用CURDATE()函数获取当前日期。

    2024-01-02
    0274
  • win11如何给其他盘增加空间

    在Windows 11操作系统中,给其他盘增加空间的方法有很多,这里我们将介绍两种常见的方法:使用磁盘管理工具和使用第三方磁盘压缩工具,本文将详细讲解这两种方法的操作步骤。方法一:使用磁盘管理工具磁盘管理工具是Windows系统中自带的一个功能强大的磁盘管理工具,可以用来调整磁盘分区、删除分区、创建新分区等,通过使用磁盘管理工具,我们……

    2023-12-14
    0179
  • sql中execute的作用是什么

    execute用于执行SQL语句,包括查询、插入、更新和删除等操作。

    2024-05-16
    0106
  • sql中的indexof函数怎么使用

    IndexOf函数用于在字符串中查找指定字符或子串的位置,语法为:string.IndexOf(substring)。如果找到,返回起始位置;否则返回-1。

    2024-05-15
    0119
  • sql中execute的用法是什么

    execute用于执行存储过程或函数,语法为:EXECUTE procedure_name [parameter1, parameter2, ...]。

    2024-05-16
    0113

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

免备案 高防CDN 无视CC/DDOS攻击 限时秒杀,10元即可体验  (专业解决各类攻击)>>点击进入