Sql Server 开窗函数Over()的使用实例详解

Sql Server 开窗函数Over()的使用实例详解

简介

开窗函数 (Window Functions),顾名思义即为 “在一组 rows 中开一个窗,然后计算在这个窗口中的函数”,它是近年来 SQL 中一大特性。

在 SQL Server 2005 版本推出 Window Functions。而在 2012 版本中,提供了更多的 Window Functions 函数,极大的丰富了 SQL 的聚合计算能力,例如 ROW_NUMBER(), RANK(), DENSE_RANK()等函数。

本文将对 SQL Server 开窗函数 Over() 的使用做出详细说明,提供两个具体的实例说明。

Over()函数

Over()函数是窗口函数中最重要的一个函数,用于定义该窗口中计算时的行为。

Over()函数的基本格式为:

OVER ([partition_by_clause] [order_by_clause] [row/clause)

partition_by_clause

通过该语句对数据进行分组,仅对当前分组执行分析函数。如果没有指定 partition_by_clause,则所有行视为一个分组。

order_by_clause

该语句用于对窗口中的行进行排序,如果省略该语句,则不会对窗口中的行做任何排序操作。

row/clause

该语句指定窗口中的行数范围,如果我们没有给出 row/clause,则窗口包含分组的所有行。

更多开窗函数相关语法可查看官方文档

实例分析

在下面的实例中,我们将通过实现对下面的表进行查询。

数据表 orders:
| 订单号 | 客户ID | 订单日期 | 订单总额 |
| ---- | ---- | ---- | ---- |
| 1 | A1 | 2021-01-01 | 100 |
| 2 | A1 | 2021-01-04 | 50 |
| 3 | A2 | 2021-01-05 | 70 |
| 4 | A2 | 2021-01-06 | 200 |
| 5 | A1 | 2021-01-07 | 300 |

实例1:查询分组后每个客户的订单号及订单总额

SELECT 
  [订单号],
  [客户ID],
  [订单总额],
  SUM ([订单总额])
    OVER (PARTITION BY [客户ID])
    AS [客户总订单额]
FROM
  orders;

执行结果:
| 订单号 | 客户ID | 订单总额 | 客户总订单额 |
| ---- | ---- | ---- | ---- |
| 2 | A1 | 50 | 450 |
| 1 | A1 | 100 | 450 |
| 5 | A1 | 300 | 450 |
| 3 | A2 | 70 | 270 |
| 4 | A2 | 200 | 270 |

分析:

  • OVER (PARTITION BY [客户ID]) 按客户ID进行分组,sum([订单总额]) 将当前窗口下客户ID的订单总额累加,输出到整列结果 AS [客户总订单额] 中;
  • 最终输出分组后的每个订单号、订单总额和客户总订单额。

实例2:查询分组后每个客户每个订单的对比情况

SELECT 
  *,
  [订单总额]
    - SUM ([订单总额]) OVER(PARTITION BY [客户ID] ORDER BY [订单日期] ASC ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
    AS [订单总额差值]
FROM orders;

执行结果:
| 订单号 | 客户ID | 订单日期 | 订单总额 | 订单总额差值 |
| ---- | ---- | ---- | ---- | ---- |
| 1 | A1 | 2021-01-01 | 100 | 0 |
| 2 | A1 | 2021-01-04 | 50 | -50 |
| 5 | A1 | 2021-01-07 | 300 | -150 |
| 3 | A2 | 2021-01-05 | 70 | 0 |
| 4 | A2 | 2021-01-06 | 200 | 130 |

分析:

  • OVER(PARTITION BY [客户ID] ORDER BY [订单日期] ASC ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) 分组按照客户ID和订单日期排序,[订单总额] 与窗口前一行的总额做差得到 [订单总额差值]
  • 最终输出分组后每个订单的差值对比结果。

结论

Over()函数的使用,是开窗函数运用的核心,对于 SQL 语言的数据维度扩展,也提供了一个全新的思维视角。

除以上两个示例,OVER()函数还可以完成更多类似计算、筛选等操作,可根据实际需求进行探索和创新。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Sql Server 开窗函数Over()的使用实例详解 - Python技术站

(0)
上一篇 2023年5月21日
下一篇 2023年5月21日

相关文章

  • 如何在Python中使用sqlite3库连接SQLite数据库?

    在 Python 中,我们可以使用 sqlite3 库来连接 SQLite 数据库。下面是如何在 Python 中使用 sqlite3 库连接 SQLite 数据库的完整使用攻略。 连接 SQLite 数据库 在使用 sqlite3 库连接 SQLite 数据库时,需要指定数据库文件的路径。下面是一个连接 SQLite 数据库的示例: import sqli…

    python 2023年5月12日
    00
  • SpringBoot+Querydsl 框架实现复杂查询解析

    关于“SpringBoot+Querydsl 框架实现复杂查询解析”的完整攻略,下面我会给出详细的讲解。该攻略主要分为以下几个部分。 1、什么是Querydsl Querydsl 是一个基于 Java 代码实现的类型安全的查询框架。它提供了一种更加易于使用的方式,帮助 Java 开发者构建复杂的查询。Querydsl 支持SQL,JPQL/HQL,JDOQL…

    database 2023年5月22日
    00
  • Linux曝出Sudo提权漏洞 任意用户亦可运行root命令

    简介 Sudo(SuperUser Do)是一种常见的在Linux系统中提升用户权限的工具。但是,最近Linux发现了一个严重的问题:Sudo存在一个提权漏洞,可以允许不受信任的用户以root权限运行任意命令。这个漏洞被命名为“Baron Samedit”,它影响的版本包括Sudo 1.8.2到1.8.31p2版本以及1.9.0到1.9.5p1版本。 漏洞利…

    database 2023年5月22日
    00
  • MySQL – change 和 modify 的区别

    表描述MySQL 中 change 和 modify 区别 更改列名 change: alter table 表名 change 旧列名 新列名 类型 只更改列属性 change: alter table 表名 列名 列名 类型 相同的列名要写两次. 更改列属性 modify: alter table 表名 列名 类型 区别:1)change 可以更改列名 …

    MySQL 2023年4月12日
    00
  • SQL 删除全表记录

    要删除一张表中所有的记录,可以使用 SQL 中的 DELETE 语句结合 WHERE 子句来完成。下面是SQL删除全表记录的完整攻略: 步骤一:备份表格数据 在执行 DELETE 语句之前,建议您先备份整张表的数据。这一步虽然不是必需的,但是如果不小心误删了数据,备份数据可以方便地帮助您找回丢失的数据。 步骤二:使用 DELETE 语句删除表格数据 执行 D…

    database 2023年3月27日
    00
  • redis操作学习记录

    关于redis操作学习记录的完整攻略,以下是详细讲解: 简介 Redis是一款非常流行的开源键值对存储数据库。由于其高性能、高可靠性、高扩展性等诸多优点,成为了互联网企业中首选的缓存和存储方案,也被广泛用于分布式应用和海量数据处理等领域。 Redis提供了丰富的数据结构、数据持久化、复制、事务、Lua脚本、pub/sub消息等功能,同时支持各种编程语言的客户…

    database 2023年5月18日
    00
  • MongoDB TTL索引的实例详解

    MongoDB TTL索引的实例详解 简介 MongoDB 中 TTL(Time To Live) 索引是一种特殊类型的索引,可以使文档在某一固定时间后自动过期。该索引可以帮助我们自动删除一些过期的数据。 在实际的业务场景中,一些数据不适合一直保存在数据库中,过期的数据可能会占用太多的空间或导致查询变得缓慢,所以我们需要及时地对它们进行清理。 TTL 索引的…

    database 2023年5月22日
    00
  • 详解MySQL数据库的内部结构

    MySQL是一个关系型数据库管理系统,它的内部结构由许多部分组成。 MySQL数据库的内部结构 MySQL数据库的内部基本上为以下结构: 缓冲池: MySQL的缓冲池也称为内存池或缓存,是MySQL中最基本和最重要的部分之一。缓冲池是一种用于优化MySQL性能的缓存技术,它将常用的数据存储在内存中,以减少从磁盘读取数据的次数。缓冲池可以减少磁盘I/O操作的频…

    MySQL 2023年3月8日
    00
合作推广
合作推广
分享本页
返回顶部