SQL与MySQL笔记

文章目录

  • SQL与MySQL笔记
  • 环境配置&基础常识
    • RDMS相关概念
    • MySQL Workbench
    • Navicat
  • SQL基础语法
    • 书写风格
    • SQL语句分类
    • SQL语句规则
    • SQL数据类型
    • SQL中的对象
    • SQL数据的约束
  • 对SQL对象的操作
    • 表的创建,删除,删除/添加列
      • 创建CREATE
      • 删除 DROP
      • 删除/添加列 ALTER
        • 添加列
        • 删除列
        • 删除行(用DELETE+WHERE)
    • 表的更新,插入行
      • 更新 UPDATE
      • 插入行数据 INSERT
    • 表的索引
      • 建立索引 3种方法
      • 索引分类
    • 各种运算符(算术`~`,比较`~`,逻辑`~`)
      • 算术运算符
      • 比较运算符
      • 逻辑运算符
    • 对表进行基础查询,排序
      • SELECT 语句
        • SELECT相关技巧
      • WHERE 语句
      • 对象(列,表)的别名 AS
    • 对表进行聚合查询
    • (查询时)常用的函数
      • 逻辑谓词
        • LIKE谓词 用于匹配部分字符串
      • 字符串函数
      • 转换函数
      • 日期函数
    • 对表的查询结果进行分组,排序
      • GROUP BY 将查询结果分组
      • HAVING 对GROUP BY分组结果进行过滤
      • ROLLUP
      • ORDER BY 将查询结果(行)排序
      • LIMIT OFFSET (排序后)只返回部分记录/跳过前几条记录
      • 子查询
        • 标量子查询
        • 关联子查询
    • (对视图)集合运算
      • 视图的加法 UNION
        • 不去重复行的UNION合并 UNION ALL
        • UNION和WHERE不搭!
      • 视图的交运算 用INNER JOIN实现
      • 视图的差运算 用NOT IN实现
      • 视图的对称差运算 用UNION+NOT IN实现
    • 表的连接 JOIN
      • 内连接 INNER JOIN
        • <内连接的应用> 关联子查询
          • 自连接的关联子查询
      • 自然连接 NATURAL JOIN
      • 外连接 OUTER JOIN
      • 交叉连接 CROSS JOIN(笛卡尔积)
      • WHERE实现连接
  • SQL控制流
    • BEGIN...END 语义块
    • IF(expr,v1,v2) 函数
      • IFNULL(v1,v2) 函数
    • CASE语句
    • IF...ELSE...语句
    • WHILE语句
  • SQL高级处理
    • 窗口函数
      • 使用方法
      • 窗口函数分类
        • 排序用的专用窗口函数
        • 聚合函数作窗口函数
        • 窗口函数指定更详细的范围

环境配置&基础常识

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 shopSET 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字句书写顺序要求很严格:
  1. 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 productGROUP 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_priceFROM product;

中的子查询语句

SELECT AVG(sale_price) FROM product) AS avg_price

返回的就是一个常量(所有商品的价格平均值),作用是增添一个名为avg_price的列,显示所有商品的均价(每一行的这个值都一样)

关联子查询

内层的子查询可以引用外层查询的对象,即内外查询间建立关联,称为关联子查询:

比如,选取出各商品种类中高于该商品种类的平均销售单价的商品:

-- 关联查询
SELECT product_id,product_name,sale_priceFROM product AS p1WHERE sale_price>(SELECT AVG(sale_price) FROM product AS p2WHERE 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_nameFROM productUNION
SELECT product_id, product_nameFROM product2;

而且UNION等集合运算会去除重复的记录(行)
对同一个表的不同查询结果合并等价于OR谓词,合并多个表则必须用UNION

不去重复行的UNION合并 UNION ALL

要同时保留两个表的重复行,在UNION后面加上ALL即可:

SELECT product_id, product_nameFROM productUNION ALL
SELECT product_id, product_nameFROM 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_nameFROM productWHERE product_id NOT IN (SELECT product_id FROM Product2)UNION        --
SELECT product_id, product_nameFROM product2WHERE product_id NOT IN (SELECT product_id FROM Product2);

表的连接 JOIN

内连接 INNER JOIN

也叫等值连接,返回两个表都符合条件的部分

FROM <表1> INNER JOIN <表2> ON <条件>;

例如:

SELECT *FROM ShopProduct AS SPINNER JOIN Product AS PON SP.product_id = P.product_id;

等价于

SELECT *FROM ShopProduct AS SP, roduct AS PWHERE 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 SPINNER JOIN Product AS PON SP.product_id = P.product_id;)WHERE shop_name = '东京'AND product_type = '衣服' ;
自连接的关联子查询

自连接就是来自同一个表的视图之间相互连接,这里用INNER JOIN
不用JOIN语句时:

SELECT product_type, product_name, sale_priceFROM product AS P1WHERE sale_price > (SELECT AVG(sale_price)FROM product AS P2WHERE P1.product_type = P2.product_typeGROUP BY product_type);

等价于——自连接的子查询:
注意JOIN的时候相同名称的列要标清楚属于哪个表

SELECT P1.product_type, P1.product_name, P1.sale_priceFROM product AS P1INNER JOIN(SELECT AVG(sale_price) AS ave_priceFROM productGROUP BY product_type) AS P2ON P1.product_type=P2.product_typeWHERE 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_nameFROM shopproduct SP, product PWHERE SP.product_id = P.product_id;

等价于

SELECT SP.shop_id,SP.shop_name,SP.product_id,P.product_nameFROM ShopProduct AS SPINNER JOIN Product AS PON 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)函数:如果表达式exprTRUE,则IF()的返回值为v1,否则返回值为v2。IF()的返回值为数字值或字符串值,具体情况视其所在的语境而定。

IFNULL(v1,v2) 函数

如果v1不为NULL,则IFNULL()返回值为v1;否则其返回值为v2

CASE语句

CASE后面有表达式时,每个WHEN后面的条件是这个表达式的一个可能取值

CASE [expr]WHEN condition1 THEN result1  WHEN condition2 THEN result2WHEN conditionN THEN resultNELSE 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 行”,加上自身行

SQL MySQL 笔记相关推荐

  1. MySQL 笔记3 -- SQL 语言

    MySQL 笔记3 – SQL 语言 MySQL 系列笔记是笔者学习.实践MySQL数据库的笔记 课程链接: MySQL 数据库基础入门教程 参考文档: MySQL 官方文档 一. SQL语言规范 S ...

  2. mysql中10049是什么错误_【学习笔记】Oracle数据库10049用于分析SQL解析笔记案例

    [学习笔记]Oracle数据库10049用于分析SQL解析笔记案例 时间:2016-11-05 13:54   来源:Oracle研究中心   作者:HTZ   点击: 次 天萃荷净 Oracle研究 ...

  3. mysql事务手写笔记_兴奋了!阿里技术官手写“MySQL笔记”,传授你年薪百万级干货...

    前言 MySQL重要吗?重要!为什么重要?因为它在Java企业级开发中非常常用,因为 MySQL 是开源免费的,并且方便扩展.阿里巴巴数据库系统也大量用到了 MySQL,因此它的稳定性是有保障的.My ...

  4. 涂抹mysql笔记-mysql复制特性

    涂抹mysql笔记-mysql复制特性 mysql复制特性:既可以实现整个服务(all databases)级别的复制,也可以只复制某个数据库或某个数据库中的某个指定的表对象.即可以实现A复制到B(主 ...

  5. MySQL 笔记9 -- PyMySQL

    MySQL 笔记9 – PyMySQL MySQL 系列笔记是笔者学习.实践MySQL数据库的笔记 参考文档: MySQL 官方文档 SQL 教程 PyMySQL官方文档 一.基础 1.简介 PyMy ...

  6. MySQL 笔记8 -- 存储过程和索引

    MySQL 笔记8 – 存储过程和索引 MySQL 系列笔记是笔者学习.实践MySQL数据库的笔记 课程链接: MySQL 数据库基础入门教程 参考文档: MySQL 官方文档 SQL 教程 一.存储 ...

  7. MySQL 笔记7 -- 权限操作与视图

    MySQL 笔记7 – 权限操作与视图 MySQL 系列笔记是笔者学习.实践MySQL数据库的笔记 课程链接: MySQL 数据库基础入门教程 参考文档: MySQL 官方文档 SQL 教程 一.权限 ...

  8. MySQL 笔记6 -- 函数与事务

    MySQL 笔记6 – 函数与事务 MySQL 系列笔记是笔者学习.实践MySQL数据库的笔记 课程链接: MySQL 数据库基础入门教程 参考文档: MySQL 官方文档 SQL 教程 一.内置函数 ...

  9. MySQL 笔记2 -- MySQL 基础

    MySQL 笔记2 – MySQL 基础 MySQL 系列笔记是笔者学习.实践MySQL数据库的笔记 课程链接: MySQL 数据库基础入门教程 参考文档: MySQL 官方文档 一.MySQL 简介 ...

最新文章

  1. linux 修改时区_如何在 Ubuntu 20.04 上设置或者修改时区
  2. 2440裸机编程之四 外部中断
  3. 使用Win7时,出现无法切换电视墙
  4. 1. max31855 热电偶至输出转换器 分析
  5. 转载+收藏 数理化地生常用软件
  6. Java已死?一眼就能看懂的Java自学手册,挑战大厂重燃激情!
  7. 下了一个游戏说计算机丢失,冰封64位win10系统下启动游戏提示计算机丢失XINPUT1-3.dll怎么办...
  8. MATLAB频谱图绘制
  9. 怎么用计算机算lnx,ln计算(log计算器在线)
  10. 学习.NET好书推荐
  11. html 播放微信amr音频文件,如何在微信中播放amr格式的文件?
  12. 利用Python+xarray+cartopy+matplotlib 实现遥感地形图制图绘制 —— xarray 学习文档01
  13. 新媒体运营,微博平台运用技巧分享
  14. radiogroup多选_为何多组RadioGroup 里面的RadioButton 会出现多选状态​?
  15. java 获取当前第几周_java 计算当前日期是今年的第几周 和 该周的开始日期及结束日期...
  16. JAVA常用类之日期处理
  17. python:二.Python教程
  18. 计算机交换机配置实验心得,交换机系统配置实验心得5
  19. SpringBoot整合Redis集群
  20. Java实现模糊查询

热门文章

  1. sqlite中的英文引号
  2. 实战商城app墨刀原型设计-商城简介
  3. Siri真的要离开我们了?
  4. drivername表示什么_driver是什么意思_driver的翻译_音标_读音_用法_例句_爱词霸在线词典...
  5. 快速软件开发——经典错误(笔记)
  6. 靠「猜」答案获得顶会最佳论文,华人IOI金牌获得者找到复杂「鸡兔同笼」最简解法...
  7. iOS swift scrollview 缩放报错
  8. Java-Appium封装实现滑动屏幕效果
  9. 发现问题和解决问题若干
  10. RD Client 苹果手机APP由于内部错误 我们无法连接到远程网关,错误0x3000064