前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >SQL窗口函数概述

SQL窗口函数概述

作者头像
用户7741497
发布于 2022-03-27 14:32:23
发布于 2022-03-27 14:32:23
2.5K00
代码可运行
举报
文章被收录于专栏:hml_知识记录hml_知识记录
运行总次数:0
代码可运行

SQL窗口函数概述

指定用于计算聚合和排名的每行“窗口框架”的函数。

窗口函数和聚合函数

在应用WHEREGROUP byHAVING子句之后,窗口函数对SELECT查询选择的行进行操作。

窗口函数将一组行中的一个(或多个)字段的值组合在一起,并在结果集中为生成的列中的每一行返回一个值。

虽然窗口函数与聚合函数类似,因为它们将多行结果组合在一起,但它们与聚合函数的不同之处在于,它们本身并不组合行。

窗函数的语法

窗口函数被指定为SELECT查询中的选择项。 窗口函数也可以在SELECT查询的ORDER BY子句中指定。

窗口函数执行与由PARTITION by子句、ORDER by子句和ROWS子句指定的逐行窗口相关的任务,并为每一行返回一个值。 这三个子句都是可选的,但是如果指定了,必须按照以下语法中的顺序指定:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
window-function() OVER (
                      [ PARTITION BY partfield ]
                      [ ORDER BY orderfield ]
                      [ ROWS framestart ] | [ ROWS BETWEEN framestart AND frameend ]
                      )

其中framestartframeend可以是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
UNBOUNDED PRECEDING |
offset PRECEDING |
CURRENT ROW |
UNBOUNDED FOLLOWING |
offset FOLLOWING
  • window-function:支持如下窗口函数:ROW_NUMBER()RANK()PERCENT_RANK()FIRST_VALUE(字段)SUM(字段)。 该字段在显示的地方是必需的,在没有显示的地方是不允许的。 括号对所有窗口函数都是必需的。
  • OVER: OVER关键字后面必须加上括号。 括号中的子句是可选的。
  • PARTITION BY partfield:一个可选子句,根据指定的partfield分区行。 Partfield可以是单个字段,也可以是用逗号分隔的字段列表。 partfield可以是聚合函数、标量函数(如LENGTH(Name)ROUND(Salary,-2)),或者表达式(如Salary+Bonus)。 部分字段不能是流字段; 尝试这样做会产生一个SQLCODE -37错误。 如果指定了PARTITION BY,必须在ORDER BY之前指定PARTITION BY

如果指定了一个PARTITION BY子句,行被分组在指定的窗口中,窗口函数创建一个新的结果集字段并为每一行分配一个值。 例如,PARTITION BY City将共享相同City字段值的所有行分组到同一个窗口中; 窗口函数根据这个分组分配行值。

  • ORDER BY orderfield:一个可选子句,根据指定的orderfield对行排序。 Orderfield可以是单个字段,也可以是用逗号分隔的字段列表。 订单字段可以是一个聚合函数,一个标量函数(例如LENGTH(Name)ROUND(Salary,-2)),或者一个表达式(例如Salary+Bonus)。 订单字段不能是流字段; 尝试这样做会产生一个SQLCODE -37错误。

ORDER BY按排序规则升序对窗口函数值进行排序。如果指定PARTITION BYORDER BY,则行将被分区为组,每个组的orderfield值将被排序,窗口函数将创建一个新的结果集字段并为每行赋值。如果在没有PARTITION BY子句的情况下指定ORDER BY子句,则所有选定的行将在单个窗口中分组、排序,然后赋值。例如,ORDER BY City根据City字段的值对所有行进行排序,然后Window函数按该顺序为每行赋值。

  • ROWS:具有两种支持的语法形式的可选子句:ROWSFRAME STARTROWS介于Frame StartFrameEnd之间。ROWS通过指定分区内的起始点和结束点(包括范围点),对分区内的连续行执行滚动操作。它需要一个ORDER BY子句来建立行序列。它可以选择性地指定PARTITION BY子句。如果未指定ROWS子句,则缺省值为从分区开始处(前面未绑定)到当前行。ROWS子句可以与first_value(Field)sum(Field)窗口函数一起使用。

简单的例子

CityTable包含具有以下值的行:

Name

City

Able

New York

Betty

Boston

Charlie

Paris

Davis

Boston

Eve

Paris

Francis

Paris

George

London

Beatrix

Paris

ROW_NUMBER()窗口函数根据指定的窗口为每一行分配一个唯一的连续整数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT Name,City,ROW_NUMBER() OVER (PARTITION BY City) FROM CityTable

Name

City

Window_3

Able

New York

1

Betty

Boston

1

Charlie

Paris

1

Davis

Boston

2

Eve

Paris

2

Francis

Paris

3

George

London

1

Beatrix

Paris

4

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT Name,City,ROW_NUMBER() OVER (ORDER BY City) FROM CityTable

本例将所有行视为单个分区。 它根据City值对行排序,并返回以下结果:

Name

City

Window_3

Able

New York

4

Betty

Boston

1

Charlie

Paris

5

Davis

Boston

2

Eve

Paris

6

Francis

Paris

7

George

London

3

Beatrix

Paris

8

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT Name,City,ROW_NUMBER() OVER (Partition BY City ORDER BY Name) FROM CityTable

这个例子根据City值对行进行分区,根据Name值对每个City分区排序,并返回以下结果:

Name

City

Window_3

Able

New York

1

Betty

Boston

1

Charlie

Paris

2

Davis

Boston

2

Eve

Paris

3

Francis

Paris

4

George

London

1

Beatrix

Paris

1

NULL

PARTITION BY子句将字段为NULL(没有分配值)的行作为分区组处理。 例如,ROW_NUMBER() OVER (Partition BY City)会将没有City值的行分配为顺序整数,就像它将顺序整数分配给City值为'Paris'的行一样。

ORDER BY子句将字段为NULL(没有分配值)的行按照在任何分配值(具有最低的排序值)之前的顺序处理。 例如,ROW_NUMBER() OVER (ORDER BY City)首先将顺序整数分配给没有City值的行,然后将顺序整数分配给排序顺序中具有City值的行。

ROWS子句将NULL(没有赋值)的字段视为值为零。 例如,SUM(Scores) OVER (ORDER BY Scores ROWS 1 above)/2将分配0.00给所有没有分数值的行((0 + 0)/2),并通过将0加到它然后除以2来处理第一个分数值。

支持的窗口函数

支持以下窗口函数:

  • FIRST_VALUE(field)——将指定窗口中第一行(ROW_NUMBER()=1)的字段列的值赋给该窗口中的所有行。 例如:FIRST_VALUE(Country) OVER (PARTITION BY City)FIRST_VALUE()支持ROWS子句。 注意,NULL排序在所有值之前,所以如果第一行中的字段值是NULL,那么窗口中的所有行都将是NULL
  • PERCENT_RANK()——将排名百分比作为0到1(包括1)之间的小数分配给同一窗口中的每一行。 如果窗口函数字段的多个行包含相同的值,那么排名百分比可能包含重复的值。
  • RANK()——给同一窗口中的每一行分配一个排序整数,从1开始。 如果窗口函数字段的多个行包含相同的值,那么对整数的排序可以包含重复的值。
  • ROW_NUMBER()——为同一窗口中的每一行分配一个唯一的连续整数,从1开始。 如果多行窗口函数字段包含相同的值,则为每一行分配一个唯一的连续整数。
  • SUM(field)——将指定窗口中字段列值的和赋给该窗口中的所有行。

SUM既可以用作聚合函数,也可以用作窗口函数。 SUM()支持ROWS子句。

下面的例子比较了这些窗口函数中ORDER by子句返回的值:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT Name,City,ROW_NUMBER() OVER (ORDER BY City) AS RowNum,
  RANK() OVER (ORDER BY City) AS RankNum,
  PERCENT_RANK() OVER (ORDER BY City) AS RankPct
  FROM CityTable ORDER BY City

本例将所有行视为单个分区。 它根据City值对行排序,并返回以下结果:

Name

City

RowNum

RankNum

RankPct

Harriet

1

1

0

Betty

Boston

2

2

.1111111111111111111

Davis

Boston

3

2

.1111111111111111111

George

London

4

4

.3333333333333333333

Able

New York

5

5

.4444444444444444444

Charlie

Paris

6

6

.5555555555555555555

Eve

Paris

7

6

.5555555555555555555

Francis

Paris

8

6

.5555555555555555555

Beatrix

Paris

9

6

.5555555555555555555

Jackson

Rome

10

10

1

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
BIO、NIO、IO多路复用模型的演进&Java NIO 网络编程
上文介绍了网络编程的基础知识,并基于 Java 编写了 BIO 的网络编程。我们知道 BIO 模型是存在巨大问题的,比如 C10K 问题,其本质就是因其阻塞原因,导致如果想要承受更多的请求就必须有足够多的线程,但是足够多的线程会带来内存占用问题、CPU上下文切换带来的性能问题,从而造成服务端崩溃的现象。怎么解决这一问题呢?优化呗,所以后面就有了NIO、AIO、IO多路复用。本文将对这几个模型详细说明并基于 Java 编写 NIO。
王二蛋
2024/01/18
7790
Java IO 与 NIO:高效的输入输出操作探究
输入输出(IO)是任何编程语言中的核心概念,而在Java中,IO操作更是应用程序成功运行的基石。随着计算机系统变得越来越复杂,对IO的要求也日益增加。在本文中,我们将探讨Java IO和非阻塞IO(NIO)的重要性以及如何在Java中实现高效的输入输出操作。
程序那些事
2023/10/17
2590
Java使用NIO实现Socket通信
在上次的博客中,已经了解到NIO当中最为重要的两个对象。分别是缓冲Buffer和通道Channel,也进行了基本的使用,不过使用的是FileChannel,主要用来与文件打交道。
半月无霜
2023/03/03
8000
Java知识点——NIO和BIO
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jvUiQgVM-1584882587306)(img/NIO图例.png)]
用户7073689
2020/03/24
3880
Java NIO?看这一篇就够了!
✎前言 现在使用NIO的场景越来越多,很多网上的技术框架或多或少的使用NIO技术,譬如Tomcat,Jetty。学习和掌握NIO技术已经不是一个JAVA攻城狮的加分技能,而是一个必备技能。在前面2篇文
方志朋
2019/06/21
1.1K0
Java NIO?看这一篇就够了!
BIO NIO AIO演变1 BIO2 NIO3 AIO4 常见面试题5 总结
Block-IO 是一种阻塞同步的通信模式。 常说的Socket IO 一般指的是BIO。是一个比较传统的通信方式,模式简单,使用方便。但并发处理能力低,通信耗时,依赖网速。
JavaEdge
2018/08/10
1.4K0
BIO NIO AIO演变1 BIO2 NIO3  AIO4 常见面试题5  总结
Java IO 模型之 BIO,NIO,AIO
应用场景:BIO 适合用于连接数比较小且固定的架构,这种方式对服务器资源要求比较高,但程序简单易理解。
Se7en258
2021/05/18
6740
Java IO 模型之 BIO,NIO,AIO
03-Java NIO 编程 入门
缓冲区(Buffer) : 缓冲区本质上是一个可以读写数据的内存块, 可以理解成是一个容器对象(含数组), 该对象提供了一组方法,可以更轻松的使用内存块,缓冲区内置了一些机制,能够跟踪和记录缓冲区的状态变化情况,Channel提供了从文件,网络读取数据的渠道,但是读取或写入的数据必须经由Buffer, 如图: [后面举例说明]
彼岸舞
2022/02/18
3940
03-Java NIO 编程 入门
Netty序章之BIO NIO AIO演变
Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能、高可靠的网络服务器和客户端程序。Netty简化了网络程序的开发,是很多框架和公司都在使用的技术。更是面试的加分项。Netty并非横空出世,它是在BIO,NIO,AIO演变中的产物,是一种NIO框架。而BIO,NIO,AIO更是笔试中要考,面试中要问的技术。也是一个很好的加分项,加分就是加工资,你还在等什么?本章带你细细品味三者的不同! 流程图:
用户1212940
2022/04/13
5430
Netty序章之BIO NIO AIO演变
BIO/NIO/AIO总结(3)
简介 NIO是一种同步非阻塞的I/O模型,在Java 1.4 中引入了 NIO 框架,对应 java.nio 包,提供了 Channel , Selector,Buffer等抽象。
黑洞代码
2021/01/19
3610
BIO/NIO/AIO总结(3)
你对Java网络编程了解的如何?Java NIO 网络编程 | Netty前期知识(二)
在 Java 1.4 中引入了 NIO 框架(java.nio 包),提供了 Channel、Selector、Buffer 等新的抽象,可以构建多路复用的、同步非阻塞 IO 程序,同时提供了更接近操作系统底层的高性能数据操作方式
宁在春
2022/10/31
3310
你对Java网络编程了解的如何?Java NIO 网络编程 | Netty前期知识(二)
【面试题精讲】javaIO模型之NIO
NIO(New I/O)是Java提供的一种非阻塞I/O模型,它在JDK 1.4中引入。与传统的I/O模型相比,NIO提供了更高效、更灵活的I/O操作方式。
程序员朱永胜
2023/10/22
2220
Java进阶(五)Java I/O模型从BIO到NIO和Reactor模式
Java I/O模型 同步 vs. 异步 同步I/O 每个请求必须逐个地被处理,一个请求的处理会导致整个流程的暂时等待,这些事件无法并发地执行。用户线程发起I/O请求后需要等待或者轮询内核I/O操作完成后才能继续执行。 异步I/O 多个请求可以并发地执行,一个请求或者任务的执行不会导致整个流程的暂时等待。用户线程发起I/O请求后仍然继续执行,当内核I/O操作完成后会通知用户线程,或者调用用户线程注册的回调函数。 阻塞 vs. 非阻塞 阻塞 某个请求发出后,由于该请求操作需要的条件不满足,请求操作一直阻塞,
Jason Guo
2018/06/19
7170
从理论到实践:深度解读BIO、NIO、AIO的优缺点及使用场景
BIO、NIO和AIO是Java编程语言中用于处理输入输出(IO)操作的三种不同的机制,它们分别代表同步阻塞I/O,同步非阻塞I/O和异步非阻塞I/O。
索码理
2023/10/10
10.4K0
从理论到实践:深度解读BIO、NIO、AIO的优缺点及使用场景
BIO、NIO、AIO原理及总结
同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销。
用户5325874
2020/04/13
8430
解开BIO、NIO、AIO神秘的面纱
本文内容涉及同步与异步, 阻塞与非阻塞, BIO、NIO、AIO等概念, 这块内容本身比较复杂, 很难用三言两语说明白. 而书上的定义更不容易理解是什么意思. 下面跟着我一起解开它们神秘的面纱。
yukong
2018/09/03
9020
解开BIO、NIO、AIO神秘的面纱
java架构之路-(netty专题)初步认识BIO、NIO、AIO
  本次我们主要来说一下我们的IO阻塞模型,只是不多,但是一定要理解,对于后面理解netty很重要的
小菜的不能再菜
2020/02/21
4570
Java IO: BIO, NIO, AIO
BIO, NIO, AIO,本身的描述都是在Java语言的基础上的。 而描述IO,我们需要从三个层面:
九州暮云
2019/08/21
7000
从BIO到NIO、AIO和零拷贝
在JAVA的网络编程方面,BIO、NIO、AIO和零拷贝是我们必须掌握的技术,它们分别代表着不同的网络编程实现方式。
青山师
2023/05/05
2060
BIO、NIO
我们平常使用的IO是BIO(Blocking-IO),即阻塞IO、而NIO(No-blocking-IO)则是非阻塞IO,二者有什么区别呢?
晚上没宵夜
2020/03/11
7810
BIO、NIO
相关推荐
BIO、NIO、IO多路复用模型的演进&Java NIO 网络编程
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验