SQL与MySQL笔记
文章目录
环境配置&基础常识
MySQL中的SQL是Structured Query Language,My是创始人Michael Widenius女儿的名字,属于关系数据库管理系统(Relational Database Management System),简称RDMS
SQL(Structured Query Language)即结构化查询语言,是一种专门用来与数据库通信的语言,与其它语言(C/C++, Python…)不同在于,SQL的关键词很少,都是描述性很强的英文单词,而且可以进行非常复杂和高级的数据库操作。
RDMS相关概念
图示:
表头(header): 每一列的名称;
列(col): 具有相同数据类型的数据的集合;
行(row): 每一行用来描述某条记录的具体信息;
值(value): 行的具体信息, 每个值必须与该列的数据类型相同;
键(key): 键的值在当前列中具有唯一性。
MySQL Workbench
选择数据库可以用USE语句,也可以直接在左边的Schemas中案直接选择要操作的数据库:
如果不用WHERE限制UPDATE或DELETE,在安全模式下会报错,可在preferences中取消勾选安全模式:
Navicat
用教育邮箱+证件申请免费证书
快速运行当前查询语句:
选中部分query语句,Ctrl+R运行
SQL基础语法
书写风格
关键字大写,其他小写最合适,SQL
SQL语句分类
DDL :Data Definition Language,数据定义语言,用来创建或者删除数据库和表等对象
包括
- CREATE:创建数据库和表等对象
- DROP: 删除数据库和表等对象
- ALTER: 修改数据库和表等对象的结构
(最重要)DML:Data Manipulation Language,数据操纵语言, 用来查询或者变更表中的记录。
包括
- SELECT :查询表中的数据
- INSERT :向表中插入新数据
- UPDATE :更新表中的数据
- DELETE :删除表中的数据
DCL :Data Control Language,数据控制语言
- COMMIT : 确认对数据库中的数据进行的变更
- ROLLBACK : 取消对数据库中的数据进行的变更
- GRANT : 赋予用户操作权限
- REVOKE : 取消用户的操作权限
SQL中90%语句为DML
SQL语句规则
- 语句以分号;结尾(同C,Java)
- 不区分关键字大小写,习惯上大写(便于阅读)
- 单词间用空格或回车分隔(同C,Java)
- win系统不区分表名及字段名大小写,教程中小写
- 常数写法固定,并且用引号引用,比如’123’, ‘2022-2-12’
- 注释的语法是
--
和/**/
,后者同C, Java
SQL数据类型
数据库每一列必须指定数据类型,且不能存储数据类型不符的数据
四种基本数据类型:
- INTEGER 型 存储整数
- CHAR型 定储定长字符串
- VARCHAR型 存储可变长度字符串
- DATE型 存储日期数据(年月日)
CHAR的字符数和VARCHAR最大字符数在创建时确定,通过括号写在里面(n)
DATE型数据可以正常地比较大小(> < >= <=
),越早的时间越小,也可用DATEDIFF()函数计算差值,用day(), year()函数截取特定时间字段的数值等
SQL中的对象
- 数据库 database
CREATE DATABASE shop;
- 表 table
CREATE TABLE product(
productId CHAR(4),
productName VARCHAR(10),
productPrice INT,
PRIMARY KEY product_id
);
- 视图 view
视图的本质是基于表(table)的虚表,实际存储的不是数据而是SELECT语句(SELECT本身表示的就是视图)
CREATE VIEW <视图名称>(<列名1>,<列名2>,...) AS <SELECT语句> --用CREATE创建视图
SELECT * FROM product; --SELECT生成的也是视图
SQL数据的约束
CREATE语句中写在数据类型之后,表示对数据追加的限制
- NOT NULL 非空限制,即该列必须输入数据。
- PRIMARY KEY 主键约束,代表该列是唯一值,可以通过该列取出特定的行的数据。
- DEFAULT 该列的默认值,比如DEFAULT 0
对SQL对象的操作
表的创建,删除,删除/添加列
分别对应DDL语句:CREATE, DROP, ALTER
创建CREATE
- 创建数据库
CREATE DATABASE <数据库名>;
USE语句选择创建的数据库 USE <数据库名>
- 创建表
CREATE TABLE <表名>(
< 列名 1> < 数据类型 > < 该列所需约束 >,
< 列名 2> < 数据类型 > < 该列所需约束 >,
...
<该表的约束1><该表的约束2>...
);
例如:
CREATE TABLE product(product_id CHAR(4) NOT NULL, --NOT NULL约束
product_name VARCHAR(100) NOT NULL,
product_type VARCHAR(32) NOT NULL,
sale_price INTEGER , --之后三项没加约束
purchase_price INTEGER ,
regist_date DATE ,
PRIMARY KEY (product_id) --product_id设为主键(对表本身的约束)
);
删除 DROP
DROP TABLE <表名>; -- 删除不可恢复,要谨慎
或者用TRUNCATE: 速度更快,而且再次使用该表时需要重新CREATE
TRUNCATE TABLE <表名>; -- 删除不可恢复,要谨慎
删除/添加列 ALTER
添加列
ALTER TABLE < 表名 > ADD COLUMN < 列的定义 >;
也就是
ALTER TABLE < 表名 > ADD COLUMN <列名><列数据类型><列约束>;
删除列
ALTER TABLE < 表名 > DROP COLUMN < 列名 >;
删除行(用DELETE+WHERE)
注意必须加WHERE, 否则所有数据会被删除
DELETE FROM product WHERE COLUMN_NAME='XXX'; --注意使用常量时加引号
表的更新,插入行
分别对应UPDATE, INSERT
更新 UPDATE
更新,也就是修改已有的数据
UPDATE <表名>
SET <列名> = <表达式>
[,<列名2>=<表达式2>...]
WHERE <条件> --和之前一样,很重要!
也可加上ORDER BY, LIMIT等子句
例如:
UPDATE shop
SET product_name='banana'
SET regist_date='2021/9/1'
WHERE product_id = '0011';
--注意这里才加分号,这四行是一条语句
将ID为’0011’的产品名改成’banana‘,注册日期改成’2021/9/1’
插入行数据 INSERT
INSERT INTO <表名> (列名1, 列名2, ……) VALUES (值1, 值2, ……);
如果是全列INSERT(每个列的数据都插入)可以省略列名清单,VALUES字句的值会自动按顺序赋给每一列(值的个数必须和列数匹配)
同时插入多行数据:也可以用一个INSERT语句完成
-- 多行INSERT ( DB2、SQL、SQL Server、 PostgreSQL 和 MySQL多行插入)
INSERT INTO productins VALUES ('0002', '打孔器', '办公用品', 500, 320, '2009-09-11'),
('0003', '运动T恤', '衣服', 4000, 2800, NULL),
('0004', '菜刀', '厨房用具', 3000, 2800, '2009-09-20');
表的索引
建立索引 3种方法
- 创建表的时候直接建立索引
CREATE TABLE tableName(
...
INDEX indexName(username(length))
);
- 用CREATE INDEX语句创建
CREATE INDEX indexName ON tableName (columnName);
- 用ALTER语句创建
ALTER table tableName ADD INDEX indexName(columnName);
索引分类
- 主键索引
- 普通索引
- 唯一索引
- 前缀索引
- 全文索引
各种运算符(算术~
,比较~
,逻辑~
)
算术运算符
+ - * \ %
和C一样
比较运算符
> < = >= <= !=
和C一样
不同之处在于SQL的比较运算符更多:
!>
不大于 !<
不小于 <>
不等于
分别等价于<= >= !=
逻辑运算符
运算符 | 描述 |
---|---|
AND | 与 |
OR | 或 |
NOT | 非,放在其他条件表达式前面,反转其输出, 如NOT (xx AND xxx ) |
IS NULL | 如果xx IS NULL为真,则xx是NULL |
NULL属于第三种逻辑值:不确定,SQL使用的是三值逻辑
和NULL的对比必须用IS NULL
或者IS NOT NULL
,不能用等号=
,NULL也不能和0对比
对表进行基础查询,排序
对应于语句SELECT, ORDER BY
SELECT 语句
查询并选取(输出)出必要数据,输出一个表头为<列名>
的子表,经常和WHERE语句一起使用:
SELECT <列名>,
FROM <表名>
WHERE <条件>; -- 经常加WHERE
SELECT相关技巧
- 选取所有列时可以用
*
代替列名:
星号*是指全部区域(all fields)
SELECT * FROM <表名>; --打印整个表
<列名>
中用AS
可以在查询结果中给该列设置别名(实际输出的列名),汉字要用双括号- <列名>前可以多加个
DISTINCT
在查询结果中删除重复数据,DISTINCT
只能和SELECT连用
SELECT product_id AS id, --用AS使用别名
product_name AS name,
FROM product;
SELECT DISTINCT product_type FROM product; --每种product_type最多只输出一次
WHERE 语句
用于指明操作范围,比如选取(SELECT)表中符合条件的数据,对行进行选取
...
WHERE <条件>; --常用逻辑运算符连接多个条件
<条件>为布尔表达式,要注意和NULL相关的条件写法
对象(列,表)的别名 AS
别名: Alias, 用AS
关键字标注,AS本身可以省略;除必须要加别名的情况外,别名可用于引用其他层的表内数据(关联查询),或者区分不同表的同名列——<表名/表的别名>.<列名>
- 列的别名:
SELECT column_name AS alias_name
FROM table_name;
- 表的别名: 紧跟在FROM<表名>后面
SELECT column_name(s)
FROM table_name AS alias_name;
嵌套查询时必须给内层的表加上别名
对表进行聚合查询
SQL中,使用聚合函数进行查询,就是聚合查询,它可以快速获得结果
- SUM:计算表中某数值列中的合计值
- AVG:计算表中某数值列中的平均值
- MAX:计算表中任意列中数据的最大值,包括文本类型和数字类型
- MIN:计算表中任意列中数据的最小值,包括文本类型和数字类型
- COUNT:计算表中的记录条数(行数)
用法:func(<单个列名>)
-- 计算销售单价和进货单价的合计值
SELECT SUM(sale_price), SUM(purchase_price)
FROM product;
-- 计算销售单价和进货单价的平均值
SELECT AVG(sale_price), AVG(purchase_price)
FROM product;
(查询时)常用的函数
逻辑谓词
区分逻辑谓词和逻辑运算符:谓词就是返回值为逻辑值的函数(SQL中为TRUE / FALSE / UNKNOWN
)
主要有:
- LIKE
- BETWEEN
- IS NULL、IS NOT NULL
- IN
- EXISTS
LIKE谓词 用于匹配部分字符串
可以和正则表达式匹配语句 REGEXP 相互换
用法:LIKE 'str'
,匹配上就返回true
常用语法:通配符
%
–代表“零个或多个任意字符串”的特殊符号
_
–下划线匹配任意 1 个字符
比如匹配包含’aad’字段的字符串:LIKE '%aad%'
字符串函数
- CONCAT – 拼接
CONCAT(str1, str2, str3)
- LENGTH – 字符串长度
LENGTH( str )
- LOWER – 小写转换
类似地有UPPER – 大写转换 - REPLACE – 字符串的替换
REPLACE( 对象字符串,替换前的字符串,替换后的字符串 )
- SUBSTRING – 字符串的字串/截取
SUBSTRING (对象字符串 FROM 截取的起始位置 FOR 截取的字符数)
- LEFT – 从字符串的左边截取
LEFT(对象字符串, 左边截取的字符数)
- RIGHT – 从字符串的右边截取
RIGHT(对象字符串, 右边截取的字符数)
起始的位置从1算起
转换函数
- CAST – 类型转换
CAST(待转换值 AS 目标类型)
- COALESCE – 将NULL转换为其他值
COALESCE(数据1,数据2,数据3……)
该函数会返回可变参数列表中左侧开始第 1个不是NULL的值,
例如如果数据1可能为空,就把用来替换数据1为NULL的值放在数据2位置上
日期函数
获取系统当前日期等,做题时用不上
对表的查询结果进行分组,排序
对应语句GROUP BY, HAVING
GROUP BY 将查询结果分组
- 用于将查询结果按照GROUP BY后面的列名分组输出,也就是根据某些列的值不同,分割成不同行显示查询结果, 经常和MIN(), MAX(), AVG()等聚合函数一起使用
SELECT <列名1>,<列名2>, ……
FROM <表名>
GROUP BY <列名1>, <列名2>, ……;
- SQL字句书写顺序要求很严格:
- SELECT ➡️ 2. FROM ➡️ 3. WHERE ➡️ 4. GROUP BY
虽然顺序要求严格,但是这不是执行顺序,比如输出每一类别的商品均价:
SELECT product_type,AVG(sale_price)
FROM product
GROUP BY product_type;
GROUP BY product_type限制了AVG()是在每个类别内计算,而不是算好整体的AVG再分组(SELECT执行在GROUP之后)
实际执行顺序:
FROM ➡️ WHERE ➡️ GROUP BY➡️ SELECT ➡️ HAVING ➡️ ORDER BY
- 使用GROUP BY与不使用的对比:
-- 不含GROUP BY 因为没有按照type展开,查询结果COUNT列混在一起
SELECT product_type, COUNT(*)
FROM product
-- GROUP BY xx 基于xx列的值对查询结果分组
SELECT product_type, COUNT(*)
FROM product
GROUP BY product_type;
分组前 vs 分组后
HAVING 对GROUP BY分组结果进行过滤
与WHERE进行区分:WHERE子句只能指定行的条件,而不是对组筛选,一个组(比如’衣服’)可以有多个行(比如0001的’T-shirt’, 0008的’夹克’)
HAVING必须和GROUP BY搭配使用,放在GROUP BY后面
SELECT product_type, COUNT(*)
FROM product
GROUP BY product_type
HAVING COUNT(*) = 2; --对列取值施加限制,筛选GROUP BY输出的组
ROLLUP
和GROUP BY 连用,用于生成总计和小计,即得到每个分组以
及每个分组汇总级别(针对每个分组)的值
SELECT product_name,product_type, sale_price
FROM product
GROUP BY product_type,product_name WITH ROLLUP;
功能为显示每一类的小计和总计(这里的每一类为GROUP BY后面的product_type),WITH ROLLUP
前面的量(product_name )在小计和总计里会显示为NULL
ORDER BY 将查询结果(行)排序
根据特定列的取值排序,默认为升序,若降序排列则在对应列名后面加DESC
SELECT <列名1>, <列名2>, ……
FROM <表名>
ORDER BY <排序基准列名1> [ASC或DESC], <排序基准列名2> [ASC或DESC], ……
注意:NULL
无法用比较运算符和其他数值比较,所以有基准列出现NULL
时,NULL
结果会展示在查询结果的开头或者末尾。
NULL
设定为比任何非NULL
值低,可以预测出现在开头还是最后
LIMIT OFFSET (排序后)只返回部分记录/跳过前几条记录
SELECT...[FROM...]
[WHERE...]
[LIMIT 强制返回的条数 OFFSET 跳过的记录条数]
LIMIT n OFFSET m
也可简写成LIMIT m, n
用前者更直观
子查询
子查询就是嵌套查询,在SELECT语句已经创建视图的基础上再用SELECT查询(SELECT的嵌套)
- 一条普通的SELECT语句:
- 在该SELECT语句生成的视图再SELECT查询(嵌套查询)
功能是将内层SELECT视图中产品数(cnt_product)不大于2的产品挑出来:
注意:随着嵌套层数增加,查询的效率会变差
标量子查询
指有的子查询返回的不是几个列,而是一个标量(常数),比如
SELECT product_id,product_name,sale_price,
(SELECT AVG(sale_price) FROM product) AS avg_price
FROM product;
中的子查询语句
SELECT AVG(sale_price) FROM product) AS avg_price
返回的就是一个常量(所有商品的价格平均值),作用是增添一个名为avg_price的列,显示所有商品的均价(每一行的这个值都一样)
关联子查询
内层的子查询可以引用外层查询的对象,即内外查询间建立关联,称为关联子查询:
比如,选取出各商品种类中高于该商品种类的平均销售单价的商品:
-- 关联查询
SELECT product_id,product_name,sale_price
FROM product AS p1
WHERE sale_price>(SELECT AVG(sale_price)
FROM product AS p2
WHERE p1.product_type=p2.product_type
GROUP BY product_type);
其中的WHERE p1.product_type=p2.product_type
就建立了内外查询之间的关联,确保了内外层讨论的是同一行(同一件商品),内层SELECT查询计算出该商品所在类别的平均价格,返回给外层以供使用
(对视图)集合运算
集合运算符有 UNION, INTERSECT, EXCEPT
,分别为集合的并,交和差。
视图的加法 UNION
将两个查询结果合并显示,例如:
SELECT product_id, product_name
FROM product
UNION
SELECT product_id, product_name
FROM product2;
而且UNION等集合运算会去除重复的记录(行)
对同一个表的不同查询结果合并等价于OR
谓词,合并多个表则必须用UNION
不去重复行的UNION合并 UNION ALL
要同时保留两个表的重复行,在UNION后面加上ALL
即可:
SELECT product_id, product_name
FROM product
UNION ALL
SELECT product_id, product_name
FROM product2; --注意这整块算一条语句(UNION相连)
UNION和WHERE不搭!
UNION是对完整的两个视图(SELECT语句)合并,而WHERE附属于SELECT内,所以无法限定UNION合并后的视图本身,UNION只适用于两个已经筛选完毕的表合并
需要对两个表在共同条件限制下合并时,宜用INNER/OUTER JOIN
例如:
视图的交运算 用INNER JOIN实现
MySQL中求交集没有专门的集合运算符,用INNER JOIN实现
JOIN用法,写在**FROM
后的列名之间**:
SELECT...
FROM <列1> (INNER) JOIN <列2>...
...
例子:
SELECT p1.product_id, p1.product_name
FROM Product p1 --AS 别名其实可以省略AS
INNER JOIN Product2 p2
ON p1.product_id=p2.product_id;
如果是一个表内的两次查询,用AND逻辑谓词即可实现交集
视图的差运算 用NOT IN实现
MySQL中求差集没有专门的集合运算符,用NOT IN实现
-- 使用 NOT IN 子句的实现方法
SELECT * FROM Product
WHERE product_id NOT IN (SELECT product_id
FROM Product2);
视图的对称差运算 用UNION+NOT IN实现
对称差:
使用UNION的同时,加上WHERE…NOT IN(另一个集合)实现对称差
SELECT product_id, product_name
FROM product
WHERE product_id NOT IN (SELECT product_id FROM Product2)
UNION --
SELECT product_id, product_name
FROM product2
WHERE product_id NOT IN (SELECT product_id FROM Product2);
表的连接 JOIN
内连接 INNER JOIN
也叫等值连接,返回两个表都符合条件的部分
FROM <表1> INNER JOIN <表2> ON <条件>;
例如:
SELECT *
FROM ShopProduct AS SP
INNER JOIN Product AS P
ON SP.product_id = P.product_id;
等价于
SELECT *
FROM ShopProduct AS SP, roduct AS P
WHERE SP.product_id = P.product_id;
也就是说,INNER JOIN和相应的WHERE语句等价:
...FROM <表1>INNER JOIN<表2>ON <条件>
等价于
...FROM <表1>, <表2> WHERE<条件>
另外注意不同表的相同列名在引用时必须加上对应的表名,以作区分
<内连接的应用> 关联子查询
有时候同一件记录对象(比如"商品")的信息会写在不同表里面,要对其进行查询前必须先将多个表用内连接合并成一个列名齐全的大表(而不是直接UNION)
SELECT *
FROM ShopProduct AS SP
INNER JOIN Product AS P
ON SP.product_id = P.product_id;
在将这个大表接在FROM后面,实现关联子查询
SELECT *
FROM (-- 第一步查询的结果
SELECT *
FROM ShopProduct AS SP
INNER JOIN Product AS P
ON SP.product_id = P.product_id;
)
WHERE shop_name = '东京'
AND product_type = '衣服' ;
自连接的关联子查询
自连接就是来自同一个表的视图之间相互连接,这里用INNER JOIN
不用JOIN语句时:
SELECT product_type, product_name, sale_price
FROM product AS P1
WHERE sale_price > (SELECT AVG(sale_price)
FROM product AS P2
WHERE P1.product_type = P2.product_type
GROUP BY product_type);
等价于——自连接的子查询:
注意JOIN的时候相同名称的列要标清楚属于哪个表
SELECT P1.product_type, P1.product_name, P1.sale_price
FROM product AS P1
INNER JOIN(
SELECT AVG(sale_price) AS ave_price
FROM product
GROUP BY product_type
) AS P2
ON P1.product_type=P2.product_type
WHERE P1.sale_price>P2.ave_price;
相比之前返回标量的方法,现在先得出所有类的平均价格表,再和原表JOIN的方法在逻辑上更好理解。
自然连接 NATURAL JOIN
自然连接就是按照两个表中都包含的列名来进行等值内连结,并且只保留一个同名列
SELECT * FROM <表1> NATURAL JOIN <表2>;
限制列名不重复后等价于INNER JOIN
外连接 OUTER JOIN
相比内连接抛弃掉两个表里不符合ON条件的行,外连接会有选择地保留无法匹配到的行。
- 左连接:保存左表中无法按照 ON 子句匹配到的行
LEFT OUTER JOIN
- 右连接:保存右表中无法按照 ON 子句匹配到的行
RIGHT OUTER JOIN
- 全外连接:保留两个表的所有行
MySQL中没有实现的方式,可以左右连接+UNION实现(或者直接UNION或UNION ALL)
要点:
- 外连接本质是提取单张表的全部信息,再和另一张表ON<条件>限制下的信息合并
- 因为链接可以交换表的位置,所以左右连接没有明显区别
交叉连接 CROSS JOIN(笛卡尔积)
不管是INNER/OUTER JOIN,将ON条件去掉就是笛卡尔积,结果为一张全部记录交叉组合的大表(**行数为两表行数的乘积
**)
WHERE实现连接
事实从多张表里SELECT,用WHERE限定条件一样可以起到连接的效果,但是语句本身没有INNER JOIN/OUTER JOIN ON 这样直观
SELECT SP.shop_id
,SP.shop_name
,SP.product_id
,P.product_name
FROM shopproduct SP, product P
WHERE SP.product_id = P.product_id;
等价于:
SELECT SP.shop_id
,SP.shop_name
,SP.product_id
,P.product_name
FROM ShopProduct AS SP
INNER JOIN Product AS P
ON SP.product_id = P.product_id;
SQL控制流
不知道为什么这么重要的内容DATAWHALE没有总结,IF…ELSE…, WHILE, FOR, CASE等语句都参与构成一个程序的控制流(Control Flow),在各类高级语言,汇编语言中都有用到,SQL没道理缺了这个
下面模板中的{}
表示可选的部分
BEGIN…END 语义块
语义块:statement_block
BEGIN
{ sql_statement | statement_block }
END
一个语义块内可以包含多条语句或者声明, 语义块本身用BEGIN…END囊括,而不是加{}
IF(expr,v1,v2) 函数
IF(expr,v1,v2)
函数:如果表达式expr
是TRUE
,则IF()的返回值为v1,否则返回值为v2。IF()的返回值为数字值或字符串值,具体情况视其所在的语境而定。
IFNULL(v1,v2) 函数
如果v1不为NULL,则IFNULL()返回值为v1;否则其返回值为v2
CASE语句
CASE后面有表达式时,每个WHEN后面的条件是这个表达式的一个可能取值
CASE [expr]
WHEN condition1 THEN result1
WHEN condition2 THEN result2
WHEN conditionN THEN resultN
ELSE result
END;
IF…ELSE…语句
ELSE可以省略
IF Boolean_expression
{ sql_statement | statement_block }
[ ELSE
{ sql_statement | statement_block } ]
WHILE语句
WHILE Boolean_expression
{ sql_statement | statement_block | BREAK | CONTINUE }
按需要可以在循环体内加入BREAK;
CONTINUE;
等语句(和C++同理)
SQL高级处理
窗口函数
窗口函数也称为OLAP函数(Online Analytical Processing),意思是对数据库数据进行实时分析处理。常规的SELECT语句都是对整张表进行查询,窗口函数可以让我们有选择的去对某一部分数据进行汇总、计算和排序。
具体为:
- PARTITON BY 每个类内部计算,排序
- ORDER BY 计算累计值(范围为目前为止排好序的部分数据)
PARTITON BY <分组用列名>是在分组并每个组内进行计算/排序
使用方法
<窗口函数> OVER ([ PARTITION BY <分组用列名> ] [ ORDER BY <排序用列名> ])
并且作为一个列写在SELECT后面
这里的 PARTITON BY 或ORDER BY 必须至少选一个,否则窗口函数没有操作的窗口(也就是所有查询行)
窗口函数分类
- RANK, DENSE_RANK等排序用的专用窗口函数
- SUM, MAX, MIN等聚合函数
排序用的专用窗口函数
只在相同位次的处理上有所不同:
- RANK函数
若存在相同位次的记录,会跳过之后的位次 - DENSE_RANK函数
即使存在相同位次的记录,会跳过之后的位次 - ROW_NUMBER函数
不会存在相同的位次,只赋予每一行连续的位次
聚合函数作窗口函数
复习:聚合函数 SUM,AVG,MAX,MIN,COUNT
-
和PARTITION BY连用:
输出的是该类的函数值
SUM:此行所在类的合计
AVG:此行所在类的均值
…(以此类推) -
和ORDER BY连用:
输出的是一个累积的聚合函数值
SUM:当前所在行及之前所有的行的合计
AVG:当前所在行及之前所有的行的均值
…(以此类推)
窗口函数指定更详细的范围
和ORDER BY连用时,可以指定更加详细的范围(称为”框图“)
即:
<窗口函数> OVER (ORDER BY <排序用列名>
ROWS n PRECEDING )
<窗口函数> OVER (ORDER BY <排序用列名>
ROWS BETWEEN n PRECEDING AND n FOLLOWING)
PRECEDING
(“之前”), 将框架指定为 “截止到之前 n 行”,加上自身行
FOLLOWING
(“之后”), 将框架指定为 “截止到之后 n 行”,加上自身行