SQLServer2022新特性Window子句

news/2024/9/13 9:34:49/文章来源:https://blog.csdn.net/zxrhhm/article/details/139241158

SQLServer2022新特性Window子句

参考官方文档
https://learn.microsoft.com/zh-cn/sql/t-sql/queries/select-window-transact-sql?view=sql-server-ver16

1、本文内容

  • 语法
  • 参数
  • 一般备注
  • 示例

1.1、新特性适用于:

  • SQL Server 2022 (16.x)
  • Azure SQL 数据库
  • Azure SQL 托管实例

在应用 OVER 子句中使用窗口的窗口函数之前,WINDOW 子句中的命名窗口定义确定行集的分区和排序。

1.2、备注

WINDOW 子句要求数据库兼容性级别为 160 或更高。 如果数据库兼容性级别低于 160,则 SQL Server 无法使用 WINDOW 子句执行查询。

可在 sys.databases 视图或数据库属性中查看兼容性级别。 可以使用以下命令更改数据库的兼容级别:

ALTER DATABASE DatabaseName SET COMPATIBILITY_LEVEL = 160

2、语法

WINDOW window_name AS ([ reference_window_name ]   [ <PARTITION BY clause> ]  [ <ORDER BY clause> ]   [ <ROW or RANGE clause> ]  )  <PARTITION BY clause> ::=  
PARTITION BY value_expression , ... [ n ]  <ORDER BY clause> ::=  
ORDER BY order_by_expression  [ COLLATE collation_name ]   [ ASC | DESC ]   [ ,...n ]  <ROW or RANGE clause> ::=  
{ ROWS | RANGE } <window frame extent>

3、参数

window_name
定义的窗口规范的名称。 OVER 子句中的窗口函数将使用此名称来引用窗口规范。 窗口名称必须符合标识符的规则。

reference_window_name
当前窗口引用的窗口的名称。 引用的窗口必须位于 WINDOW 子句中定义的窗口之间。

其他参数包括:

  • PARTITION BY:将查询结果集分为多个分区。

  • ORDER BY:定义结果集的每个分区中行的逻辑顺序。

  • ROWS/RANGE:通过指定分区中的起点和终点来限制分区中的行数。

有关参数的更多具体详细信息,请参阅 OVER 子句
https://learn.microsoft.com/zh-cn/sql/t-sql/queries/select-over-clause-transact-sql?view=sql-server-ver16

4、一般备注

可在 WINDOW 子句中定义多个命名窗口。

通过使用后跟附加规范的 window_name,可将附加组件添加到 OVER 子句中的命名窗口。 但是,不能在 OVER 子句中重新定义 WINDOW 子句中指定的属性。

当查询使用多个窗口时,一个命名窗口可以使用 window_name 引用另一个命名窗口。 在这种情况下,必须在引用窗口的窗口定义中指定引用 window_name。 一个窗口中定义的窗口组件不能由另一个引用它的窗口重新定义。

根据在 window 子句中定义窗口的顺序,允许向前和向后的窗口引用。 换句话说,一个窗口可使用在它所属的 <window_expression> 中定义的任何其他窗口作为 reference_window_name,而不管它们的定义顺序如何。 不允许循环引用和在单个窗口中使用多个窗口引用。

<window_expression> 中包含的已定义窗口的新 window_name 的范围由属于 <window_expression> 的任何窗口定义,以及包含该 window 子句的 <query_specification> 或 的 SELECT 子句组成。 如果 <window_expression> 包含在属于简单表查询 <query_expression> 的 <query_specification> 中,则新 window_name 的范围还包括该 <query_expression> 的 <order_by_expression>(如果有)。

OVER 子句中窗口规范与基于语义的聚合函数和分析函数的使用限制适用于 WINDOW 子句。

5、示例

5.1、 指定在 window 子句中定义的窗口

测试表及数据准备

create table t_order_sales(
order_id varchar(4) primary key,
user_no varchar(8),
amount int,
create_date datetime
);
insert into t_order_sales values ('1001','C0001',1920,'2020-01-01');
insert into t_order_sales values ('1002','C0002',3510,'2019-03-02');
insert into t_order_sales values ('1003','C0003',3500,'2022-04-12');
insert into t_order_sales values ('1004','C0004',8030,'2021-05-10');
insert into t_order_sales values ('1005','C0011',9600,'2023-03-12');
insert into t_order_sales values ('1006','C0002',5021,'2022-01-05');
insert into t_order_sales values ('1007','C1002',6160,'2018-01-06');
insert into t_order_sales values ('1008','C2007',3201,'2024-01-10');
insert into t_order_sales values ('1009','C3008',8760,'2023-01-16');
insert into t_order_sales values ('1010','V0002',8870,'2021-01-22');SELECT * FROM dbo.t_order_sales;order_id user_no  amount      create_date
-------- -------- ----------- -----------------------
1001     C0001    1920        2020-01-01 00:00:00.000
1002     C0002    3510        2019-03-02 00:00:00.000
1003     C0003    3500        2022-04-12 00:00:00.000
1004     C0004    8030        2021-05-10 00:00:00.000
1005     C0011    9600        2023-03-12 00:00:00.000
1006     C0002    5021        2022-01-05 00:00:00.000
1007     C1002    6160        2018-01-06 00:00:00.000
1008     C2007    3201        2024-01-10 00:00:00.000
1009     C3008    8760        2023-01-16 00:00:00.000
1010     V0002    8870        2021-01-22 00:00:00.000

指定在 window 子句中定义的窗口


SELECT ROW_NUMBER() OVER win AS "Row Number",order_id,user_no,amount,create_date
FROM t_order_sales
WINDOW win AS (ORDER BY amount DESC)
GORow Number           order_id user_no  amount      create_date
-------------------- -------- -------- ----------- -----------------------
1                    1005     C0011    9600        2023-03-12 00:00:00.000
2                    1010     V0002    8870        2021-01-22 00:00:00.000
3                    1009     C3008    8760        2023-01-16 00:00:00.000
4                    1004     C0004    8030        2021-05-10 00:00:00.000
5                    1007     C1002    6160        2018-01-06 00:00:00.000
6                    1006     C0002    5021        2022-01-05 00:00:00.000
7                    1002     C0002    3510        2019-03-02 00:00:00.000
8                    1003     C0003    3500        2022-04-12 00:00:00.000
9                    1008     C2007    3201        2024-01-10 00:00:00.000
10                   1001     C0001    1920        2020-01-01 00:00:00.000(10 行受影响)

以下查询与上述查询等效,但不使用 WINDOW 子句。

Row Number           order_id user_no  amount      create_date
-------------------- -------- -------- ----------- -----------------------
1                    1005     C0011    9600        2023-03-12 00:00:00.000
2                    1010     V0002    8870        2021-01-22 00:00:00.000
3                    1009     C3008    8760        2023-01-16 00:00:00.000
4                    1004     C0004    8030        2021-05-10 00:00:00.000
5                    1007     C1002    6160        2018-01-06 00:00:00.000
6                    1006     C0002    5021        2022-01-05 00:00:00.000
7                    1002     C0002    3510        2019-03-02 00:00:00.000
8                    1003     C0003    3500        2022-04-12 00:00:00.000
9                    1008     C2007    3201        2024-01-10 00:00:00.000
10                   1001     C0001    1920        2020-01-01 00:00:00.000(10 行受影响)

5.2、在多个 over 子句中指定单个窗口

SELECT order_id,user_no,amount,create_date,SUM(amount) OVER win AS Total,AVG(amount) OVER win AS "Avg",COUNT(amount) OVER win AS "Count",MIN(amount) OVER win AS "Min",MAX(amount) OVER win AS "Max"
FROM t_order_sales
WHERE user_no IN ('C0002','V0002')
WINDOW win AS (PARTITION BY user_no);
GOorder_id user_no  amount      Total       Avg         Count       Min         Max
-------- -------- ----------- ----------- ----------- ----------- ----------- -----------
1002     C0002    3510        8531        4265        2           3510        5021
1006     C0002    5021        8531        4265        2           3510        5021
1010     V0002    8870        8870        8870        1           8870        8870(3 行受影响)

以下查询与上述查询等效,但不使用 WINDOW 子句。

SELECT order_id,user_no,amount,SUM(amount) OVER (PARTITION BY user_no) AS Total,AVG(amount) OVER (PARTITION BY user_no) AS "Avg",COUNT(amount) OVER (PARTITION BY user_no) AS "Count",MIN(amount) OVER (PARTITION BY user_no) AS "Min",MAX(amount) OVER (PARTITION BY user_no) AS "Max"
FROM t_order_sales
WHERE user_no IN ('C0002','V0002');
GOorder_id user_no  amount      Total       Avg         Count       Min         Max
-------- -------- ----------- ----------- ----------- ----------- ----------- -----------
1002     C0002    3510        8531        4265        2           3510        5021
1006     C0002    5021        8531        4265        2           3510        5021
1010     V0002    8870        8870        8870        1           8870        8870(3 行受影响)

5.3、在 window 子句中定义通用规范

SELECT order_id,user_no,amount,SUM(amount) OVER win AS Total,AVG(amount) OVER(win PARTITION BY user_no) AS Avg,COUNT(amount) OVER(win ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING) AS Count
FROM t_order_sales
WHERE user_no IN ('C0002','V0002')
WINDOW win AS (ORDER BY user_no, create_date);
GOorder_id user_no  amount      Total       Avg         Count
-------- -------- ----------- ----------- ----------- -----------
1002     C0002    3510        3510        3510        2
1006     C0002    5021        8531        4265        3
1010     V0002    8870        17401       8870        3(3 行受影响)

以下查询与上述查询等效,但不使用 WINDOW 子句。

SELECT order_id,user_no,amount,SUM(amount) OVER (ORDER BY user_no, create_date) AS Total,AVG(amount) OVER (PARTITION BY user_no ORDER BY user_no, create_date) AS Avg,COUNT(amount) OVER(ORDER BY user_no, create_date ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING) AS Count
FROM t_order_sales
WHERE user_no IN ('C0002','V0002');
GO

5.4、 向前和向后的窗口引用

此示例显示在 WINDOW 子句中定义新窗口时,将命名窗口用作前向引用和向后引用。

SELECT order_id,user_no,amount,SUM(amount) OVER win2 AS Total,AVG(amount) OVER win1 AS Avg
FROM t_order_sales
WHERE user_no IN ('C0002','V0002')
WINDOW win1 AS (win3),win2 AS (ORDER BY user_no),win3 AS (win2 PARTITION BY user_no);
GOorder_id user_no  amount      Total       Avg
-------- -------- ----------- ----------- -----------
1002     C0002    3510        8531        4265
1006     C0002    5021        8531        4265
1010     V0002    8870        17401       8870(3 行受影响)

6、总结

Window 子句通常与 OVER() 子句相关,它经常与窗口函数(如 ROW_NUMBER(), RANK(), DENSE_RANK(), SUM(), AVG(), MIN(), MAX() 等函数的 OVER() 版本)一起使用。这些窗口函数允许你在结果集的每个行上执行计算,这些计算会考虑与当前行相关的其他行(例如,前面的几个示例)

SQL Server 中与窗口函数相关的一般知识或最佳实践,那么以下是一些要点:

  • 使用 OVER() 子句:通过为窗口函数指定 OVER() 子句,你可以定义窗口的边界和排序顺序。
  • PARTITION BY:在 OVER() 子句中使用 PARTITION BY 可以将数据分成多个分区,并为每个分区独立地计算窗口函数。
  • ORDER BY:在 OVER() 子句中使用 ORDER BY 可以定义窗口中行的顺序。这对于需要基于行顺序(如累积总和或运行平均值)的计算特别有用。
  • 常见的窗口函数:包括 ROW_NUMBER(), RANK(), DENSE_RANK(), SUM() OVER(), AVG() OVER(), MIN() OVER(), MAX() OVER() 等。
  • 性能考虑:窗口函数可能会对性能产生影响,特别是在处理大量数据时。确保你的查询已针对性能进行了优化,并考虑使用索引、分区等策略来加速查询。
  • 兼容性:不同的数据库系统对窗口函数的支持可能有所不同。在将使用窗口函数的查询从一个系统迁移到另一个系统时,请务必检查目标系统的兼容性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ldbm.cn/p/430653.html

如若内容造成侵权/违法违规/事实不符,请联系编程新知网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服务器感染了. rmallox勒索病毒,如何确保数据文件完整恢复?

导言&#xff1a; 近年来&#xff0c;随着信息技术的飞速发展&#xff0c;网络安全问题日益凸显。其中&#xff0c;勒索病毒作为一种严重的网络威胁&#xff0c;对个人和企业数据造成了巨大的威胁。本文将重点介绍.rmallox勒索病毒的特点、传播途径以及应对策略&#xff0c;旨…

云原生架构内涵_3.主要架构模式

云原生架构有非常多的架构模式&#xff0c;这里列举一些对应用收益更大的主要架构模式&#xff0c;如服务化架构模式、Mesh化架构模式、Serverless模式、存储计算分离模式、分布式事务模式、可观测架构、事件驱动架构等。 1.服务化架构模式 服务化架构是云时代构建云原生应用的…

什么是访问控制漏洞

什么是AC Bugs&#xff1f; 实验室 Vertical privilege escalation 仅通过隐藏目录/判断参数来权限控制是不安全的&#xff08;爆破url/爬虫/robots.txt/Fuzz/jsfinder&#xff09; Unprotected functionality 访问robots.txt 得到隐藏目录&#xff0c;访问目录 &#xff0c;…

markdown语法保存

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

【漏洞复现】大华智能物联综合管理平台 log4j远程代码执行漏洞

0x01 产品简介 大华ICC智能物联综合管理平台对技术组件进行模块化和松耦合&#xff0c;将解决方案分层分级&#xff0c;提高面向智慧物联的数据接入与生态合作能力。 0x02 漏洞概述 大华ICC智能物联综合管理平台/evo-apigw/evo-brm/1.2.0/user/is-exist 接口处存在 l0g4i远程…

大模型“1元购”?AI公司加速奔向应用端“大航海时代”

自字节跳动发布豆包大模型&#xff0c;互联网大厂纷纷就位&#xff0c;击穿“地板价”的打法从C端向B端拓展。这也成为今年“618”最亮眼的价格战。 5月15日&#xff0c;字节跳动率先宣布豆包大模型已通过火山引擎开放给企业客户&#xff0c;大模型定价降至0.0008元/千Tokens&…

手机端如何访问本地vue+vite项目,实现实时调试?

一、应用场景 h5&#xff08;vuevite&#xff09;嵌入app后&#xff0c;出现某种问题时&#xff0c;需要每次发布坏境后&#xff0c;才能才看效果&#xff0c;这种来回很耗时间&#xff0c;本文章在于解决手机端直接访问本地启动应用项目&#xff0c;无需重复发布坏境 二、实…

【本地运行chatgpt-web】启动前端项目和service服务端项目,也是使用nodejs进行开发的。两个都运行成功才可以使用!

1&#xff0c;启动web界面 https://github.com/Chanzhaoyu/chatgpt-web#node https://nodejs.org/en/download/package-manager # 使用nvm 安装最新的 20 版本。 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source /root/.bashrc n…

网络应用层之(1)DHCPv6协议

网络应用层之(1)DHCPv6协议 Author: Once Day Date: 2024年5月26日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章可参考专栏: 通信网络技术_Once-Day的博客-C…

做场外个股期权怎么询价

做场外个股期权怎么询价&#xff1f;没有具体的哪家做市商是询价是最低的&#xff0c;个人投资者需要通过机构通道方询价进行对比&#xff0c;各券商的报价由询价机构方提供给到投资者&#xff0c;可以参考不同券商的报价进行比对&#xff0c;再决定是否进行投资。本文来自&…

GPT-4o:重塑人机交互的未来

一个愿意伫立在巨人肩膀上的农民...... 一、推出 在人工智能&#xff08;AI&#xff09;领域&#xff0c;自然语言处理&#xff08;NLP&#xff09;技术一直被视为连接人类与机器的桥梁。近年来&#xff0c;随着深度学习技术的快速发展&#xff0c;NLP领域迎来了前所未有的变革…

vmware中Ubuntu虚拟机和本地电脑Win10互相ping通

初始状态 使用vmware17版本安装的Ubuntu的20版本&#xff0c;安装之后什么配置都要不懂&#xff0c;然后进行下述配置。 初始的时候是NAT&#xff0c;没动的. 设置 点击右键编辑“属性” 常规选择“启用”&#xff1a; 高级选择全部&#xff1a; 打开网络配置&#xff0c;右键属…

Django入门全攻略:从零搭建你的第一个Web项目

系列文章目录 努力ing Django入门全攻略&#xff1a;从零搭建你的第一个Web项目努力ing… 文章目录 系列文章目录前言一、Django1.1 Django安装1.2 Django项目创建1.3 目录介绍 二、子应用2.1 子应用创建2.2 目录结构2.3 子应用注册2.4 子应用视图逻辑2.4.1 编写视图2.4.2 编写…

SpringBoot——整合Thymeleaf模板

目录 模板引擎 新建一个SpringBoot项目 pom.xml application.properties Book BookController bookList.html ​编辑 项目总结 模板引擎 模板引擎是为了用户界面与业务数据分离而产生的&#xff0c;可以生成特定格式的页面在Java中&#xff0c;主要的模板引擎有JSP&…

LazyVim笔记

回到上次编辑的位置 gi非常的方便。 neo-tree KeyDescriptionMode<leader>beBuffer Explorern<leader>eExplorer NeoTree (Root Dir)n<leader>EExplorer NeoTree (cwd)n<leader>feExplorer NeoTree (Root Dir)n<leader>fEExplorer NeoTree (c…

Facebook的魅力:数字时代的社交热点

在当今数字化时代&#xff0c;社交媒体已经成为人们日常生活中不可或缺的一部分&#xff0c;而Facebook作为其中的巨头&#xff0c;一直以其独特的魅力吸引着全球数十亿用户。本文将深入探讨Facebook的魅力所在&#xff0c;以及它在数字时代的社交热点。 1. 社交网络的霸主&…

系统架构设计师【第3章】: 信息系统基础知识 (核心总结)

文章目录 3.1 信息系统概述3.1.1 信息系统的定义3.1.2 信息系统的发展3.1.3 信息系统的分类3.1.4 信息系统的生命周期3.1.5 信息系统建设原则3.1.6 信息系统开发方法 3.2 业务处理系统&#xff08;TPS&#xff09;3.2.1 业务处理系统的概念3.2.2 业务处理系统的功能 …

Linux Tcpdump抓包入门

Linux Tcpdump抓包入门 一、Tcpdump简介 tcpdump 是一个在Linux系统上用于网络分析和抓包的强大工具。它能够捕获网络数据包并提供详细的分析信息&#xff0c;有助于网络管理员和开发人员诊断网络问题和监控网络流量。 安装部署 # 在Debian/Ubuntu上安装 sudo apt-get install…

TH方程学习(1)

一、背景介绍 根据CW方程的学习&#xff0c;CW方程的限制条件为圆轨道&#xff0c;不考虑摄动&#xff0c;二者距离相对较小。TH方程则可以将物体间的相对运动推广到椭圆轨道的二体运动模型&#xff0c;本部分将结合STK的仿真功能&#xff0c;联合考察TH方程的有用性&#xff…

最长递增子序列,交错字符串

第一题&#xff1a; 代码如下&#xff1a; int lengthOfLIS(vector<int>& nums) {//dp[i]表示以第i个元素为结尾的最长子序列的长度int n nums.size();int res 1;vector<int> dp(n, 1);for (int i 1; i < n; i){for (int j 0; j < i; j){if (nums[i]…