SQL笔记

本笔记是根据SQL基础教程(MICK第2版)的学习笔记。粗略的记录了该书第二章到第七章的基础内容。后续会继续更新。

DDL(Database Definition Language,数据定义语言)

数据库和表的创建

创建数据库CREATE DATABASE 数据库名称
表的创建CREATE TABLE 表名

表内容的创建

 CREATE TABLE 表名  
     (列名1   <数据类型>  <该列所需约束>,  
      列名2   <数据类型>  <该列所需约束>,  
      列名3   <数据类型>  <该列所需约束>,  
     ... ...  
     <该表约束1>,<该表约束2>,... ...)

约束:NOT NULL 约束; 表的主键约束(PRIMARY KEY(列名))等。

表的删除和更新

删除表(无法恢复)DROP TABLE 表名
添加列:ALTER TABLE <表名> ADD COLUMN <列的定义(包括数据类型和约束)>
删除列ALTER TABLE <表名> DROP COLUMN <列名>
变更表名RENAME TABLE <旧表名> TO <新表名>

DML(Database Manipulation Language,数据操纵语言)

列的查询

基本SELECT语句SELECT <列名>,... ... FROM <表名>; 查询某列数据;当要查询所有列时,用 * 代表全部列。

设定别名(可以是中文,需要双引号"")

SELECT <列名> AS <别名>,  
       ... ...  
FROM <表名> 

书写常数

SELECT <字符串常数> AS <列名>, 
         <数字常数> AS <列名>, 
         <日期常数> AS <列名> 
FROM <表名>

如下图 string、number、date:
MYSQL基础学习笔记

删除重复行:在 SELECT 中使用 DISTINCT 实现。

SELECT DISTINCT <列1>,
                <列2>,
                ... ... 
 FROM <表名>

注意:NULL也会作为一类数据,会合并该列其它 NULL 的数据。
MYSQL基础学习笔记

WHERE语句:通过WHERE 子句来指定查询数据的条件。执行顺序:先通过 WHERE 子句查询出符合指定条件的记录,再选取出 SELECT 语句指定的列。

SELECT <列名>,... ... 
FROM <表名> 
WHERE (条件表达式);  

注释:单行注释 -- 、多行注释 /* */ .

运算符

+、-、*、/ 称为算术运算符
SELECT <列名>,... ... , <运算操作> FROM <表名>
1、可以用括号提升运算表达式的优先级;
2、所有包含 NULL 的计算,结果肯定是 NULL

比较运算符

MYSQL基础学习笔记
注意:

  • 1、对字符串使用比较运算符时的注意事项: 比较的是字典排序顺序。
    MYSQL基础学习笔记
  • 2、不能对NULL使用比较运算符
逻辑运算符

NOT:对条件取反。
AND:“并且”的意思。在其两侧的查询条件都成立时,整个查询条件才成立。
OR:“或者”的意思。在其两侧的查询条件任意一个成立时,整个查询条件就成立。

MYSQL使用的是——三值逻辑
TRUE、FALSE、UNKNOWN(不确定)
MYSQL基础学习笔记

聚合与排序

聚合函数

常用的5个函数:
MYSQL基础学习笔记

  • 通常,聚合函数会对 NULL 以外的对象进行汇总。
  • COUNT( * ) 会得到包含 NULL 的数据行数,而 COUNT(<列名>) 会得到NULL之外的数据行数。
  • MAX/MIN 函数几乎适用于所有数据类型的列。SUM/AVG 函数只适用于数值类型的列。
  • 在聚合函数的参数中使用 DISTINCT ,可以去掉重复数据。
分组
  • 聚合键中包含NULL时,在结果中会以“不确定”行(空行)的形式表现出来。
  • 使用聚合函数和GROUP BY子句时需要注意以下4点。
    ① 只能写在SELECT子句之中
    ② GROUP BY子句中不能使用SELECT子句中列的别名
    ③ GROUP BY子句的聚合结果是无序的
    ④ WHERE子句中不能使用聚合函数

常见问题

  • 使用GROUP BY子句时,SELECT子句中不能出现聚合键之外的列名。
  • GROUP BY子句中不能使用SELECT子句中定义的别名。
  • GROUP BY 子句显示的结果是无序的。
  • 只有SELECT子句和HAVING子句(以及ORDER BY子句)中能够使用聚合函数。
为聚合结果指定条件

HAVING:对聚合函数结果指定条件。构成要素:常数,聚合函数,GROUP BY 子句中指定列名(聚合键)。

  SELECT <列名1>, ... ...     
  FROM <TABLE>    
  GROUP BY <列名1>, ... ...    
  HAVING <分组结果对应的条件>

例子:可以在 HAVING 后使用SELECT 中的别名。
MYSQL基础学习笔记

注意

  • WHERE 子句 = 指定行所对应的条件
  • HAVING 子句 = 指定组所对应的条件
  • 在 WHERE 子句和HAVING 子句中都可以使用的条件,最好写在WHERE子句中。(因为可以减少排序行数和创建索引,以提高性能。)

排序

数据库查询的排列顺序是随机的。
ORDER BY:对列进行排序(默认是升序ASC ),如需降序排序用关键字DESC

  • ORDER BY子句中可以使用SELECT子句中定义的别名。
  • ORDER BY 子句中可以使用SELECT 中的列,也可以使用存在于表中、但并不包含在 SELECT 子句之中的列。
  • ORDER BY子句中可以使用SELECT子句中未使用的列和聚合函数。
  • ORDER BY子句中不要使用列编号。

各语句的书写排序:MYSQL基础学习笔记
各语句的执行顺序:
MYSQL基础学习笔记

数据的更新

插入语句
INSERT INTO <表名> (列1, 列2, 列3, ……) 
            VALUES (值1, 值2, 值3, ……); 

其中 (列1, 列2, 列3, ……)称为列清单,(值1, 值2, 值3, ……)称为值清单。插入数据时,两个的列数要保持一致,否则会报错。

  • 原则上,执行一次INSERT语句应插入一行数据。
    MYSQL基础学习笔记

列清单的省略
对表进行全列 INSERT 时,可以省略表名后的列清单。这时 VALUES 子句的值会默认按照从左到右的顺序赋给每一列。

插入默认值
显式方法:用 DEFAULT 代替值。
隐式方法:在列清单和值清单中省略该列。

  • 省略 INSERT 语句中的列名,就会自动设定为该列的默认值(没有默认值时会设定 为NULL)。

从其他表中复制数据
插入查询得到的数据:

INSERT INTO <表1> (<列1><列2>, ... ...)  
            SELECT <列1>,<列2>, ... ... 
            FROM <表2>
  • INSERT语句的SELECT语句中,可以使用WHERE子句或者GROUP BY子句等任何SQL语法(但使用ORDER BY子句并不会产生任何效果)。
删除数据

DROP TABLE 语句可以将表完全删除 ;
DELETE 语句会留下表(容器),而删除表中的全部数据。

语法一:DELETE FROM <表名>DELETE FROM <表名> WHERE

  • DELETE语句的删除对象并不是表或者列,而是记录(行)。
  • 可以通过 WHERE 子句指定对象条件来删除部分数据。
  • SELECT 语句不同的是,DELETE语句中不能使用 GROUP BYHAVINGORDER BY三类子句.

语法二: TRUNCATE <表名>

  • 只能删除表中全部数据,不能使用WHERE
  • 可以缩短执行时间。
更新数据
UPDATE <表名>   
SET <列名> = <表达式>; 

:将列中的所有值更新为新的值。——会将列中 NULL 值更新为新值。

指定条件的 UPDATE 语句:

UPDATE <表名>   
SET <列名> = <表达式> 
WHERE <条件>;  
  • 使用UPDATE 语句可以将值清空为 NULL(但只限于未设置NOT NULL约束的列)。

多列更新
MYSQL基础学习笔记

  • 需要注意的是第一种方法——使用逗号将列进行分隔排列,这一方法在所有的DBMS 中都可以使用。但是第二种方法——将列清单化(元组),这一方法在某些 DBMS中是无法使用的。
事务

事务是对表中数据进行更新的单位。简单来讲,事务就是需要在同一个处理单元中执行的一系列更新处理的集合。
创建事务

事务开始语句;
    DML语句1;    
    DML语句2;    
    DML语句3;   
    事务结束语句(COMMIT或者ROLLBACK);
  • 事务的开始语句:
    MYSQL基础学习笔记
  • COMMIT 是提交事务包含的全部更新处理的结束指令,相当于文件处理中的覆盖保存。一旦提交,就无法恢复到事务开始前的状态了。
  • ROLLBACK 是取消事务包含的全部更新处理的结束指令,数据库会恢复到事务开始之前的状态.

ACID特性

  • 原子性(Atomicity):指在事务结束时,其中所包含的更新处理要么全部执行,要
    么完全不执行。
  • 一致性(Consistency):一致性指的是事务中包含的处理要满足数据库提前设置的约束,如主键约束或者 NOT NULL 约束等。
  • 隔离性(Isolation):隔离性指的是保证不同事务之间互不干扰的特性。
  • 持久性(Durability):持久性也可以称为耐久性,指的是在事务(不论是提交还是回滚)结束后,DBMS 能够保证该时间点的数据状态会被保存的特性——日志。

复杂查询

视图
表中存储的是实际数据,而视图中保存的是从表中取出数据所使用的SELECT语句。
优点:
  • 视图无需保存数据,可以节省存储设备的容量。
  • 可以将频繁使用的 SELECT 语句保存成视图,就不用每次都重新书写 SELECT 语句。

创建视图:

# SELECT 中列与视图列要一一对应
CREATE VIEW 视图名称(<视图列名1>, <视图列名2>, ……) 
AS 
<SELECT 语句>

注意:可以使用多重视图,但应该避免在视图的基础上创建视图。

限制:

  • 定义视图时不能使用ORDER BY 子句。(PostgreSQL例外)
  • 如果定义视图的 SELECT 语句能够满足某些条件,那这个视图就可以被更新。具有代表性的条件有:① SELECT 子句中未使用 DISTINCT ② FROM 子句中只有一张表 ③ 未使用 GROUP BY 子句 ④ 未使用 HAVING 子句。
    (视图和表需要同时进行更新,因此通过汇总得到的视图无法进行更新。)

删除视图:

DROP VIEW 视图名称(<视图列名1>, <视图列名2>, ……)
子查询
子查询是一次性视图(SELECT语句)。与视图不同,子查询在`SELECT`语句执行完毕之后会消失。

使用方法 :将用来定义视图的 SELECT语句直接用于 FROM 子句当中。
SELECT 的嵌套结构(先内再外)。
可以使用嵌套结构添加子查询层数。(但是,随着子查询嵌套层数的增加,SQL 语句会变得越来越难读懂, 性能会越来越差。)

标量子查询

标量子查询就是返回单一值的子查询。
MYSQL基础学习笔记

使用地方: 能够使用常数或者列名的 地方,无论是 SELECT 子句、GROUP BY 子句、HAVING 子句,还是 ORDER BY 子句,几乎所有的地方都可以使用。

注意事项

  • 该标量子查询绝对不能返回多行结果。

关联子查询:在细分的组内进行比较时,需要使用关联子查询。

  • 关联子查询会在细分的组内进行比较时使用。
  • 关联子查询和GROUP BY子句一样,也可以对表中的数据进行切分。
  • 关联子查询的结合条件如果未出现在子查询之中就会发生错误。
    MYSQL基础学习笔记

函数、谓词、CASE表达式

函数

新数据类型:NUMERIC (全体位数,小数位)

算术函数
ABS(数值) :绝对值
MOD(被除数,除数):求余数
ROUND (对象数,小数保留位数) :保留小数位

字符串函数
拼接函数: MYSQL:CONCAT ( )、 SQL Server:+ 、 其它:||
LENGTH (字符串):字符串长度
LOWER (字符串):英文大写转小写
UPPER (字符串):英文小写转大写
REPLACE (字符串对象,替换前字符,替换字符):替换字符中某字符(三者中有一NULL就无法替换)。
SUBSTRING (对象字符串 FROM 截取的起始位置 FOR 截取的字符数):截取字符串

日期函数
CURRENT_DATE:获取当前日期(无时间)[SQL Server]
CURRENT_TIME:获取当前时间 [SQL Server]
CURRENT_TIMESTAMP:获取当前日期和时间
EXTRACT(日期元素 FROM 日期):截取日期元素,即年、月、时、分(返回数值类型)[SQL Server]
MYSQL基础学习笔记

转换函数
CAST(转换前的值 AS 想要转换的数据类型):转换某个值的数据类型
COALESCE(数据1,数据 2,数据 3……):将 NULL 转换成其它值

谓词: 谓词是需要满足返回值是真值的函数。
LIKE :字符串的部分一致查询(%(n个任意字符)、( _ 任意一个字符));
BETWEEN :范围查询(包含临界值)
IS NULL、IS NOT NULL :判断是否为NULL
IN 、 NOT IN :简化多个 OR 的谓词

  • 在使用 IN 和NOT IN 时是无法选取出 NULL 数据。
  • 能够将表和视图作为 IN 的参数。
  • 可以使用子查询作为参数
    EXISTS 、NOT EXISTS :“判断是否存在满足某种条件的记录
  • 通常指定关联子查询作为EXIST的参数。
  • 作为EXIST参数的子查询中经常会使用 SELECT *
    MYSQL基础学习笔记
CASE表达式

什么是CASE表达式
(条件)分支函数。可以分为简单CASE表达式和搜索CASE表达式(包含了简单表达式的所有功能)。

搜索表达式:
CASE WHEN <求值表达式> THEN <表达式>     
     WHEN <求值表达式> THEN <表达式>     
     WHEN <求值表达式> THEN <表达式>      
     ... ...  
     ELSE <表达式> 
END

可以使用 CASE 表示式实现行列转换:
MYSQL基础学习笔记

简单表达式:简化书写,对CASE表达式求值,再对该值进行筛选

CASE <表达式>    
WHEN <表达式> THEN <表达式>    
WHEN <表达式> THEN <表达式>    
WHEN <表达式> THEN <表达式>        
... ... 
ELSE <表达式> 
END

集合运算

集合运算,是对满足同一规则的记录进行的加减等四则运算。  
表的加减法(增减行数)

UNION(并集) :进行记录加法运算的集合运算符。UNION 后面添加 ALL 选项,可以包含重复行的集合运算。
UNION 等集合运算符通常都会除去重复的记录。

注意事项

  • 作为运算对象的记录的列数必须相同
  • 作为运算对象的记录中列的类型必须一致
  • 可以使用任何SELECT语句,但ORDER BY子句只能在最后使用一次

INTERSECT(交集) :选取两个记录集合中公共部分。[ MYSQL ]

EXCEPT(差集) :进行减法运算的集合运算符。[ MYSQL ]

联结(添加列)
  • 1、两个表中都包含的列
  • 2、只存在于一张表内的列
  • 3、将该表的列添加到另一张表

内联结
INNER JOIN:内联结。只能选取出同时存在于两张表中的数据。

SELECT <表别名 . 列名> ... ...
FROM <表1> INNER JOIN <表2>
ON  <联结条件>
WHERE ...

内联结要点

  • 需要在FROM子句中使用多张表;
  • 进行内联结时必须使用ON子句,并且要书写在 FROMWHERE 之间。
  • 使用联结时 SELECT 子句中的列需要按照 <表的别名>.<列名> 的格式进行书写。

外联结
RIGHT/LEFT OUTER JOIN:结果中包含原表中不存在(在原表之外)的信息。

SELECT <表别名 . 列名> ... ...
FROM <表1> RIGHT OUTER JOIN <表2>
ON  <联结条件>
WHERE ...

外联结要点

  • 只要数据存在于某一张表当中,就能够读取出来
  • 指定主表的关键字是 LEFTRIGHT

相关文章: