第8章 SQL高级处理:8-1 窗口函数

● 窗口函数可以进行排序、生成序列号等一般的聚合函数无法实现的高级操作。
● 理解PARTITION BY和ORDER BY这两个关键字的含义十分重要。


■什么是窗口函数

在Oracle和 SQL Server中称为分析函数。但是 MySQL 的5.7版本还是不支持窗口函数。
OLAP 是 OnLine Analytical Processing 的简称,意思是对数据库数据进行实时分析处理。 例如,市场分析、创建财务报表、创建计划等日常性商务工作。
窗口函数就是为了实现 OLAP 而添加的标准 SQL 功能。

■窗口函数的语法

窗口函数大体可以分为以下两种。

① 能够作为窗口函数的聚合函数( SUM、 AVG、 COUNT、 MAX、 MIN)
② RANK、 DENSE_RANK、 ROW_NUMBER 等专用窗口函数


■语法的基本使用方法——使用RANK函数

正如其名称所示, RANK 是用来计算记录排序的函数。

例如,对于之前使用过的 Product 表中的 8 件商品,让我们根据不同的商品种类(product_type),按照销售单价(sale_price)从低到高的顺序排序,结果如下所示。

PARTITION BY 在横向上对表进行分组,而 ORDER BY决定了纵向排序的规则。

ORDER BY 能够指定按照哪一列、何种顺序进行排序。可以通过关键字ASC/DESC 来指定升序和降序。
省略该关键字时会默认按照 ASC,也就是升序进行排序。

通过 PARTITION BY 分组后的记录集合称为窗口。此处的窗口并非“窗户”的意思,而是代表范围。


■无需指定PARTITION BY

使用窗口函数时起到关键作用的是 PARTITION BY 和 GROUP BY。
其中, PARTITION BY 并不是必需的,也就是将整个表作为一个大的窗口来使用。

■专用窗口函数的种类

● RANK函数
计算排序时,如果存在相同位次的记录,则会跳过之后的位次。
例)有 3 条记录排在第 1 位时:1 位、1 位、1 位、4 位……
● DENSE_RANK函数
同样是计算排序,即使存在相同位次的记录,也不会跳过之后的位次。
例)有 3 条记录排在第 1 位时:1 位、1 位、1 位、2 位……
● ROW_NUMBER函数
赋予唯一的连续位次。
例)有 3 条记录排在第 1 位时:1 位、2 位、3 位、4 位……

除此之外,各 DBMS 还提供了各自特有的窗口函数。上述 3 个函数(对于支持窗口函数的 DBMS 来说)在所有的 DBMS 中都能够使用。

■窗口函数的适用范围

窗口函数只能书写在一个特定的位置,这个位置就是 SELECT 子句之中。

反过来说,就是这类函数不能在WHERE 子句或者 GROUP BY 子句中使用。

之所以在ORDER BY子句中能够使用窗口函数,是因为ORDER BY子句会在SELECT子句之后执行,并且记录保证不会减少。

■作为窗口函数使用的聚合函数

所有的聚合函数都能用作窗口函数,其语法和专用窗口函数完全相同。

在按照时间序列的顺序,计算各个时间的销售额总额等的时候,通常都会使用这种称为累计的统计方法。
使用其他聚合函数时的操作逻辑也和本例相同。例如,使用 AVG 来代替 SELECT 语句中的 SUM(代码清单 8-5)。

像这样以“自身记录(当前记录)”作为基准进行统计,就是将聚合函数当作窗口函数使用时的最大特征。

■计算移动平均

窗口函数就是将表以窗口为单位进行分割,并在其中进行排序的函数。

其实其中还包含在窗口中指定更加详细的汇总范围的备选功能,该备选功能中的汇总范围称为框架。
其语法如代码清单 8-6 所示,需要在 ORDER BY 子句之后使用指定范围的关键字。

●指定框架(汇总范围)

这里我们使用了 ROWS(“行”)和 PRECEDING(“之前”)两个关键
字,将框架指定为“截止到之前 ~ 行”,因此“ROWS 2 PRECEDING”

就是将框架指定为“截止到之前 2 行”,也就是将作为汇总对象的记录限
定为如下的“最靠近的 3 行”。
● 自身(当前记录)
● 之前1行的记录
● 之前2行的记录
也就是说,由于框架是根据当前记录来确定的,因此和固定的窗口不同,其范围会随着当前记录的变化而变化。
这样的统计方法称为移动平均(moving average)。由于这种方法在希望实时把握“最近状态”时非常方便,因此常常会应用在对股市趋势的实时跟踪当中。
使用关键字 FOLLOWING(“之后”)替换 PRECEDING,就可以指定“截止到之后 ~ 行”作为框架了。

●将当前记录的前后行作为汇总对象

具体来说,就是将如下 3 行作为汇总对象来进行计算

● 之前1行的记录
● 自身(当前记录)
● 之后1行的记录


■两个ORDER BY

OVER 子句中的 ORDER BY 只是用来决定窗口函数按照什么样的顺序进行计算的,对结果的排列顺序并没有影响。

SQL基础教程(第2版)第8章 SQL高级处理:8-1 窗口函数的更多相关文章

  1. 推荐《SQL基础教程(第2版)》中文PDF+源代码+习题答案

    我认为<SQL基础教程(第2版)>非常适合数据库学习的初学者.论述的角度是读者的角度,会换位思考到读者在看到这一段时候会发出怎样的疑问,非常难得:原始数据的例题只有一道,但是可以反复从不同 ...

  2. 笔记-Python基础教程(第二版)第一章

    第一章 快速改造:基础知识 01:整除.乘方 (Python3.0之前 如2.7版本) >>> 1/2 ==>0 1/2整除,普通除法: 解决办法1: 1.0/2.0  ==& ...

  3. [SQL基础教程] 5-1视图

    [SQL基础教程] 5-1视图 视图和表 从SQL角度看视图就是一张表 视图与表的差别 表保存了实际的数据,视图保存的是SELECT语句: 视图的优点 节省存储空间: 将常用的Select 语句保存成 ...

  4. SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章)

    SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章) 示例数据库:点我 CHAPTER 08 数据修改 8.1 插入数据 8.1.1 INSERT VALUES 语句 8.1 ...

  5. [SQL基础教程] 4-4 事务

    [SQL基础教程] 4 数据更新 4-4 事务 事务 需要在同一处理单元中执行的一系列更新处理的集合 创建事务 事务开始语句; DML语句1; DML语句2; . . . 事务结束语句; 事务开始语句 ...

  6. [SQL基础教程] 4-3 数据的更新(UPDATE)

    [SQL基础教程] C4 数据更新 4-3 数据的更新(UPDATE) UPDATE UPDATE <表名> SET <列名> = <表达式>; UPDATE &l ...

  7. [SQL基础教程] 4-2 数据删除(DELETE)

    [SQL基础教程] C4 数据更新 4-2 数据删除(DELETE) DROP TABLE / DELETE DROP TABLE - 完全删除表 DELETE - 仅删除数据,保留表容器 DELET ...

  8. [SQL基础教程] 4-1 数据的插入(INSERT)

    [SQL基础教程] C4 数据更新 4-1 数据的插入(INSERT) INSERT INSERT INTO <表名>(列1,列2...) VALUES(值1,值2...); 清单 用() ...

  9. [SQL基础教程] 3-4 对查询结果进行排序/ORDER BY

    [SQL基础教程] 3-4 对查询结果进行排序/ORDER BY ORDER BY SELECT <列名1>,<列名2>,<列名2>... FROM ORDER B ...

  10. [SQL基础教程] 3-3 HAVING

    [SQL基础教程] 3-3 HAVING HAVING子句 SELECT col_1,col_2 FROM table GROUP BY col_1,col_2 HAVING col_1 = '2'; ...

随机推荐

  1. class(二)--派生类的继承

    前言 从我之前的一篇笔记对象的继承中, 我们可以知道JS的继承方式依赖原型链,而比较好的继承方式是寄生组合式继承 先来温习下什么是寄生组合式继承 function Rectangle(length, ...

  2. Docker-harbor-V1.3.0 ”私有仓库“搭建 Easy

    准备: centos     7.0 Docker version 1.12.6    docker-compose version 1.19.0   1: updata-yum:   更新yum 源 ...

  3. UVA - 1513 Movie collection (树状数组)

    题意:有n个影碟,标号为1~n,位置为0~n-1,每次取出一个影碟看完后,将其放在最前面(标号为0处),问每个影碟取出前,其位置之前有多少个影碟. 分析: 1.数组大小开为100000*2,后1000 ...

  4. Codeforces 2A :winner

    A. Winner time limit per test 1 second memory limit per test 64 megabytes input standard input outpu ...

  5. 108-PHP类成员protected和private成员属性不能被查看数值

    <?php class mao{ //定义猫类 public $age; //定义多个成员属性 protected $weight; private $color; } $mao1=new ma ...

  6. Spark SQL 笔记

    Spark SQL 简介 SparkSQL 的前身是 Shark, SparkSQL 产生的根本原因是其完全脱离了 Hive 的限制.(Shark 底层依赖于 Hive 的解析器, 查询优化器) Sp ...

  7. 实验吧-密码学-Decode、困在栅栏里的凯撒

    Decode 这是一个多重加密. 0x253464253534253435253335253433253661253435253737253464253531253666253738253464253 ...

  8. 13 装备的添加和移除(Unity3D)

    本案例主要实现功能如下:1.创建UI界面,包含两个装备栏,四个武器选择栏以及显示人物的属性的文本框2.每一个装备都有自己的属性(AD/AP/AR/MP)3.人物也有自己的基础属性(AD/AP/AR/M ...

  9. 吴裕雄--天生自然C++语言学习笔记:C++ 接口(抽象类)

    接口描述了类的行为和功能,而不需要完成类的特定实现. C++ 接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念. 如果类中至少有一个函数被声明为纯虚 ...

  10. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-tint

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...