Task05:SQL高级处理
5.1 窗口函数
5.1.1 窗口函数概念及基本的使用方法
窗口函数也称为OLAP函数。OLAP 是OnLine AnalyticalProcessing 的简称,意思是对数据库数据进行实时分析处理。
为了便于理解,称之为窗口函数。常规的SELECT语句都是对整张表进行查询,而窗口函数可以让我们有选择的去某一部分数据进行汇总、计算和排序。
窗口函数的通用形式:
<窗口函数> OVER ([PARTITION BY <列名>]
ORDER BY <排序用列名>)
*[]中的内容可以省略。
窗口函数最关键的是搞明白关键字PARTITON BY和ORDER BY的作用。
PARTITON BY是用来分组,即选择要看哪个窗口,类似于GROUP BY 子句的分组功能,但是PARTITION BY 子句并不具备GROUP BY 子句的汇总功能,并不会改变原始表中记录的行数。
ORDER BY是用来排序,即决定窗口内,是按那种规则(字段)来排序的。
举个栗子:
SELECT product_name
,product_type
,sale_price
,RANK() OVER (PARTITION BY product_type
ORDER BY sale_price) AS ranking
FROM product
得到的结果是:

我们先忽略生成的新列 - [ranking], 看下原始数据在PARTITION BY 和 ORDER BY 关键字的作用下发生了什么变化。
PARTITION BY 能够设定窗口对象范围。本例中,为了按照商品种类进行排序,我们指定了product_type。即一个商品种类就是一个小的"窗口"。
ORDER BY 能够指定按照哪一列、何种顺序进行排序。为了按照销售单价的升序进行排列,我们指定了sale_price。此外,窗口函数中的ORDER BY与SELECT语句末尾的ORDER BY一样,可以通过关键字ASC/DESC来指定升序/降序。省略该关键字时会默认按照ASC,也就是
升序进行排序。本例中就省略了上述关键字 。

5.2 窗口函数种类
大致来说,窗口函数可以分为两类。
一是 将SUM、MAX、MIN等聚合函数用在窗口函数中
二是 RANK、DENSE_RANK等排序9用的专用窗口函数
5.2.1 专用窗口函数
- RANK函数
计算排序时,如果存在相同位次的记录,则会跳过之后的位次。
例)有 3 条记录排在第 1 位时:1 位、1 位、1 位、4 位……
- DENSE_RANK函数
同样是计算排序,即使存在相同位次的记录,也不会跳过之后的位次。
例)有 3 条记录排在第 1 位时:1 位、1 位、1 位、2 位……
- ROW_NUMBER函数
赋予唯一的连续位次。
例)有 3 条记录排在第 1 位时:1 位、2 位、3 位、4 位
运行以下代码:
SELECT product_name
,product_type
,sale_price
,RANK() OVER (ORDER BY sale_price) AS ranking
,DENSE_RANK() OVER (ORDER BY sale_price) AS dense_ranking
,ROW_NUMBER() OVER (ORDER BY sale_price) AS row_num
FROM product

5.2.2 聚合函数在窗口函数上的使用
聚合函数在开窗函数中的使用方法和之前的专用窗口函数一样,只是出来的结果是一个累计的聚合函数值。
运行以下代码:
SELECT product_id
,product_name
,sale_price
,SUM(sale_price) OVER (ORDER BY product_id) AS current_sum
,AVG(sale_price) OVER (ORDER BY product_id) AS current_avg
FROM product;


可以看出,聚合函数结果是,按我们指定的排序,这里是product_id,当前所在行及之前所有的行的合计或均值。即累计到当前行的聚合。
5.3 窗口函数的的应用 - 计算移动平均
在上面提到,聚合函数在窗口函数使用时,计算的是累积到当前行的所有的数据的聚合。 实际上,还可以指定更加详细的汇总范围。该汇总范围成为框架frame)。
语法
<窗口函数> OVER (ORDER BY <排序用列名>
ROWS n PRECEDING )
<窗口函数> OVER (ORDER BY <排序用列名>
ROWS BETWEEN n PRECEDING AND n FOLLOWING)
PRECEDING(“之前”), 将框架指定为 “截止到之前 n 行”,加上自身行
FOLLOWING(“之后”), 将框架指定为 “截止到之后 n 行”,加上自身行
BETWEEN 1 PRECEDING AND 1 FOLLOWING,将框架指定为 “之前1行” + “之后1行” + “自身”
执行以下代码:
SELECT product_id
,product_name
,sale_price
,AVG(sale_price) OVER (ORDER BY product_id
ROWS 2 PRECEDING) AS moving_avg
,AVG(sale_price) OVER (ORDER BY product_id
ROWS BETWEEN 1 PRECEDING
AND 1 FOLLOWING) AS moving_avg
FROM product
执行结果:
注意观察框架的范围。
ROWS 2 PRECEDING:

ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING:

5.3.1 窗口函数适用范围和注意事项
- 原则上,窗口函数只能在SELECT子句中使用。
- 窗口函数OVER 中的ORDER BY 子句并不会影响最终结果的排序。其只是用来决定窗口函数按何种顺序计算。
5.4 GROUPING运算符
5.4.1 ROLLUP - 计算合计及小计
常规的GROUP BY 只能得到每个分类的小计,有时候还需要计算分类的合计,可以用 ROLLUP关键字。
SELECT product_type
,regist_date
,SUM(sale_price) AS sum_price
FROM product
GROUP BY product_type, regist_date WITH ROLLUP
得到的结果为:


这里ROLLUP 对product_type, regist_date两列进行合计汇总。结果实际上有三层聚合,如下图 模块3是常规的 GROUP BY 的结果,需要注意的是衣服 有个注册日期为空的,这是本来数据就存在日期为空的,不是对衣服类别的合计; 模块2和1是 ROLLUP 带来的合计,模块2是对产品种类的合计,模块1是对全部数据的总计。
ROLLUP 可以对多列进行汇总求小计和合计。

练习题
5.1
请说出针对本章中使用的 product(商品)表执行如下 SELECT 语句所能得到的结果。
SELECT product_id
,product_name
,sale_price
,MAX(sale_price) OVER (ORDER BY product_id) AS Current_max_price
FROM product
product_id product_name sale_price Current_max_price
0001 T恤 1000 1000
0002 打孔器 500 1000
0003 运动T恤 4000 4000
0004 菜刀 3000 4000
0005 高压锅 6800 6800
0006 叉子 500 6800
0007 擦菜板 880 6800
0008 圆珠笔 100 6800
5.2
继续使用product表,计算出按照登记日期(regist_date)升序进行排列的各日期的销售单价(sale_price)的总额。排序是需要将登记日期为NULL 的“运动 T 恤”记录排在第 1 位(也就是将其看作比其他日期都早)
SELECT product_id
,product_name
,sale_price
,regist_date
,SUM(sale_price) OVER (ORDER BY regist_date) AS current_sum_sale
FROM product
5.3
思考题
① 窗口函数不指定PARTITION BY的效果是什么?
② 为什么说窗口函数只能在SELECT子句中使用?实际上,在ORDER BY 子句使用系统并不会报错。
① 如果不指定就会全表排序,不会分为一个个的小窗口
② 执行顺序FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
窗口函数是为了动态分析处理,在SELECT子句可以进行筛选,而ORDER BY子句中只是用来排序,无法实现相应功能。
Task05:SQL高级处理的更多相关文章
- SQL 高级查询(层次化查询,递归)
SQL 高级查询 前面我们写了一下 SQL 的极简入门,今天来说点高级查询.没看到的朋友可以点击下面链接查看. 1 小时 SQL 极速入门(一) 1 小时 SQL 极速入门(二) 1 小时 SQL 极 ...
- SQL高级查询技巧
SQL高级查询技巧 1.UNION,EXCEPT,INTERSECT运算符 A,UNION 运算符 UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重 ...
- Oracle SQL高级编程——分析函数(窗口函数)全面讲解
Oracle SQL高级编程--分析函数(窗口函数)全面讲解 注:本文来源于:<Oracle SQL高级编程--分析函数(窗口函数)全面讲解> 概述 分析函数是以一定的方法在一个与当前行相 ...
- 13Microsoft SQL Server SQL 高级事务,锁,游标,分区
Microsoft SQL Server SQL高级事务,锁,游标,分区 通过采用事务和锁机制,解决了数据库系统的并发性问题. 9.1数据库事务 (1)BEGIN TRANSACTION语句定义事务的 ...
- 一些SQL高级函数
一些SQL高级函数 Posted on 2010-08-08 21:34 moss_tan_jun 阅读(311) 评论(0) 编辑 收藏 长度与分析用 datalength(Char_expr) 返 ...
- oracle学习笔记(十七) PL/SQL高级应用
PL/SQL高级应用 动态SQL 在PL/SQL中,不能直接执行DDL(create,alter,drop),得使用动态SQL,当然,除了DDL,动态SQL也可以执行DML(select,insert ...
- oracle sql 高级编程 历史笔记整理
20130909 周一 oracle sql 开发指南 第7章 高级查询 1.层次化查询select level,ttt.*,sys_connect_by_path(ttt.col1,',') fro ...
- SQL基础教程(第2版)第8章 SQL高级处理:8-2 GROUPING运算符
第8章 SQL高级处理:8-2 GROUPING运算符 ■ GROUPING SETS——取得期望的积木● 只使用GROUP BY子句和聚合函数是无法同时得出小计和合计的.如果想要同时得到,可以使用G ...
- SQL基础教程(第2版)第8章 SQL高级处理:8-1 窗口函数
第8章 SQL高级处理:8-1 窗口函数 ● 窗口函数可以进行排序.生成序列号等一般的聚合函数无法实现的高级操作.● 理解PARTITION BY和ORDER BY这两个关键字的含义十分重要. ■什么 ...
- Oracle学习(二)SQL高级--表数据相关
SQL高级语句 top / limit / rownum / percent (前XXX条数据) --top(SQL Server / MS Access) select top 条数 from 表; ...
随机推荐
- Spring SPI 机制总结
1.概念: SPI(Service Provider Interface)服务提供接口,简单来说就是用来解耦,实现插件的自由插拔,具体实现方案可参考JDK里的ServiceLoader(加载class ...
- 混部之殇-论云原生资源隔离技术之CPU隔离(一)
作者 蒋彪,腾讯云高级工程师,10+年专注于操作系统相关技术,Linux内核资深发烧友.目前负责腾讯云原生OS的研发,以及OS/虚拟化的性能优化工作. 导语 混部,通常指在离线混部(也有离在线混部之说 ...
- 数据结构之Set | 让我们一块来学习数据结构
数组(列表).栈.队列和链表这些顺序数据结构对你来说应该不陌生了.现在我们要学习集合,这是一种不允许值重复的顺序数据结构.我们将要学到如何创建集合这种数据结构,如何添加和移除值,如何搜索值是否存在.你 ...
- ThreadLocal引起的一次线上事故
> 线上用户存储数据后查看提示无权限 前言 不知道什么时候年轻的我曾一度认为Java没啥难度,没有我实现不了的需求,没有我解不了的bug 直到我遇到至今难忘的一个bug . 线上用户存储数据后查 ...
- 数据库和SQL概述
一.数据库的概念 1.DB 数据库(database):存储数据的"仓库".它保存了一系列有组织的数据. 2.DBMS 数据库管理系统(Database Management Sy ...
- Jenkins 基础篇 - 小试牛刀
现在我们来创建一个简单的 Jenkins 任务,这个任务输出 Java 版本信息和系统信息,通过这个任务我们先了解创建 Jenkins 任务的流程,以及了解一些对任务的基础设置,接下来就是演示任务的整 ...
- 15.Git
1.Git介绍 1.1版本控制(理解) 无论是代码编写,还是文档编写,我们都会遇到对文档内容反复修改的情况 1.2开发中存在的问题(理解) 程序员小明负责的模块就要完成了,就在即将提交发布之前的一瞬间 ...
- 【Web前端HTML5&CSS3】08-盒模型补充
笔记来源:尚硅谷Web前端HTML5&CSS3初学者零基础入门全套完整版 目录 盒模型补充及田径场实战 1. 盒子大小 2. 轮廓 3. 阴影 4. 圆角 圆 椭圆 盒模型补充及田径场实战 1 ...
- Swagger简明教程
一.什么是swagger Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化RESTful风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法, ...
- prometheus管理api
健康检查:GET /-/healthy 准备检查:GET /-/ready 停止服务:PUT|POST /-/quit 重载配置文件 PUT|POST /-/reload reference mana ...