SQL通用语法
SQL语句可以单行或多行书写,以分号结尾
SQL语句可以使用空格/缩进来增强语句的可读性
MySQL数据库的SQL语句不区分大小写,关键字建议使用大写
注释
单行注释:-- 注释内容 或 # 注释内容
多行注释:/* 注释内容 */
标题
SQL分类
DDL:数据定义语言,用来定义数据库对象(数据库,表,字段)
DML:数据操作语言,用来对数据库表中的数据进行增删改
DQL:数据查询语言,用来查询数据库中表的记录
DCL:数据控制语言,用来创建数据库用户、控制数据库的访问权限
DDL-数据库定义
创建数据库
create database [ if not exists ] 数据库名 [ default charset 字符集 ] [ collate 排序规则 ];
删除数据库
drop database [ if exists ] 数据库名;
切换数据库
use 数据库名;
查询数据库
查询所有数据库
show databases;
查询当前数据库
select database();
DDL-表定义
创建表
create table 表名(
字段1 类型 [comment 字段1注释 ],
字段2 类型 [comment 字段2注释 ],
字段3 类型 [comment 字段3注释 ],
…
字段n 字段n类型 [comment 字段n注释 ]
) [ comment 表注释 ];
删除表
删除表
drop table [ if exists ] 表名;
删除指定表, 并重新创建表
truncate table 表名;
修改表
添加字段
alter table 表名 add 字段名 类型 (长度) [ comment 注释 ] [ 约束 ];
删除字段
alter table 表名 drop 字段名;
修改字段类型
alter table 表名 modify 字段名 新数据类型 (长度);
修改字段名和字段类型
alter table 表名 change 旧字段名 新字段名 类型 (长度) [ comment 注释 ] [ 约束 ];
修改表名
alter table 表名 rename to 新表名;
rename table 旧表名to 新表名;
查询表
查询当前数据库所有表
show tables;
查看指定表结构
desc 表名;
查询指定表的建表语句
show create table 表名;
DML-表操作(增删改)
添加数据
给指定字段添加数据
insert into 表名 (字段名1, 字段名2, …) values (值1, 值2, …);
给全部字段添加数据
insert into 表名 values (值1, 值2, …);
批量添加数据
insert into 表名 (字段名1, 字段名2, …) values (值1, 值2, …),
(值1, 值2, …),
(值 1, 值2, …);
删除数据
delete from 表名 [ where 条件 ] ;
修改数据
update 表名 set 字段名1 = 值1 , 字段名2 = 值2 , … [ where 条件 ] ;
DQL-表操作(查询)
语法结构
select
[聚合函数]字段列表
from
表名列表
[where]
条件列表
[group by]
分组字段列表
[having]
分组后条件列表
[order by]
排序字段列表
[limit]
分页参数
基础查询
查询多个字段
select 字段1, 字段2, 字段3 … from 表名 ;
select * from 表名 ; (效率低)
字段设置别名
select 字段1 [ as 别名1 ] , 字段2 [ as 别名2 ] … from 表名;
select 字段1 [ 别名1 ] , 字段2 [ 别名2 ] … from 表名;
去除重复记录
select distinct 字段列表 from 表名;
条件查询
语法
select 字段列表 from 表名 where 条件列表 ;
条件
比较运算符 | 功能 |
---|---|
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
= | 等于 |
!= 或 <> | 不等于 |
between…and… | 在某个范围之内(含最小、最大值) |
in(…) | 在in之后的列表中的值,多选一 |
like | 模糊匹配(_匹配单个字符,%匹配任意个字符) |
null | 是NULL |
逻辑运算符 | 功能 |
---|---|
and 或 && | 并且(多个条件同时成立) |
or 或 || | 或者(多个条件任意一个) |
not 或 ! | 非,不是 |
聚合函数
将一列数据作为一个整体,进行纵向计算 ,null值是不参与所有聚合函数运算的
常见的聚合函数
函数 | 功能 |
---|---|
count() | 统计数量 |
max() | 最大值 |
min() | 最小值 |
avg() | 平均值 |
sum() | 求和 |
分组查询
语法
select 字段列表 from 表名 [ where 条件 ] group by 分组字段名 [ having 分组后过滤条件 ];
where与having区别
- 执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组,而having是分组之后对结果进行过滤
- 判断条件不同:where不能对聚合函数进行判断,而having可以
注意事项
- 分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义
- 执行顺序: where > 聚合函数 > having ;
- 支持多字段分组, 具体语法为 : group by columnA,columnB
排序查询
语法
select 字段列表 from 表名 order by 字段1 排序方式1 ,字段2 排序方式2;
排序方式
- asc : 升序(默认值)
- desc: 降序
- 如果是升序, 可以不指定排序方式ASC
- 如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序
分页查询
语法
select 字段列表 from 表名 limit 起始索引, 查询记录数;
注意事项
- 起始索引从0开始,起始索引 = (查询页码 - 1)* 每页显示记录数
- 如果查询的是第一页数据,起始索引可以省略,直接简写为 limit 10
- 分页查询是数据库的方言,不同的数据库有不同的实现,MySQL中是LIMIT
单表查询书写顺序
select - from - where - group by - having - order by - limit
单表查询执行顺序
from - where - group by - having - select - order by - limit
函数
字符串函数
函数 | 功能 |
---|---|
concat(s1,s2,…sn) | 字符串拼接,将S1,S2,… Sn拼接成一个字符串 |
lower(str) | 将字符串str全部转为小写 |
upper(str) | 将字符串str全部转为大写 |
lpad(str,n,pad) | 左填充,用字符串pad对str的左边进行填充,达到n个字符串长度 |
rpad(str,n,pad) | 右填充,用字符串pad对str的右边进行填充,达到n个字符串长度 |
trim(str) | 去掉字符串头部和尾部的空格 |
substring(str,start,len) | 返回从字符串str从start位置起的len个长度的字符串 |
数值函数
函数 | 功能 |
---|---|
ceil(x) | 向上取整 |
floor(x) | 向下取整 |
mod(x,y) | 返回x/y的模 |
rand() | 返回0~1内的随机数 |
round(x,y) | 求参数x的四舍五入的值,保留y位小数 |
日期函数
函数 | 功能 |
---|---|
curdate() | 返回当前日期 |
curtime() | 返回当前时间 |
now() | 返回当前日期和时间 |
year(date) | 获取指定date的年份 |
month(date) | 获取指定date的月份 |
day(date) | 获取指定date的日期 |
date_add(date,interval expertype) | 返回一个日期/时间值加上一个时间间隔exprtype后的时间值 |
datediff(date1,date2) | 返回起始时间date1 和 结束时间date2之间的天数 |
流程函数
函数 | 功能 |
---|---|
if(value, t, f) | 如果value为true,则返回t,否则返回f |
ifnull(value1 , value2) | 如果value1不为空,返回value1,否则返回value2 |
case when [ val1 ] then [res1] … else [ default ] end | 如果val1为true,返回res1,… 否则返回default默认值 |
case [ expr ] when [ val1 ] then [res1] … else [ default ] end | 如果expr的值等于val1,返回 res1,… 否则返回default默认值 |
约束
概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据
目的:保证数据库中数据的正确、有效性和完整性
注意:约束是作用于表中字段上的,可以在创建表/修改表的时候添加约束
not null | 非空约束 | 限制该字段的数据不能为null |
unique | 唯一约束 | 保证该字段的所有数据都是唯一、不重复的 |
primary key | 主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 |
auto_increment | 自增约束 | 创建后自动加1 |
default | 默认约束 | 保存数据时,如果未指定该字段的值,则采用默认值 |
check | 检查约束(8.0.16版本 之后) | 保证字段值满足某一个条件 |
foreign key | 外键约束 | 用来让两张表的数据之间建立连接,保证数据的一致性和完整性 |
外键约束
用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性
添加外键
create table 表名(
字段名 数据类型,
…
[constraint] [外键名称] foreign key (外键字段名) references 主表 (主表列名)
);
alter table 表名 add constraint 外键名称 foreign key (外键字段名)
references 主表 (主表列名) ;
删除外键
alter table 表名 drop foreign key 外键名称;
删除/更新行为
alter table 表名 add constraint 外键名称 foreign key (外键字段) references 主表名 (主表字段名) on update 行为on delete 行为;
行为 | 说明 |
---|---|
no action | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。 (与 restrict 一致) 默认行为 |
restrict | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。 (与 no action 一致) 默认行为 |
cascade | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则也删除/更新外键在子表中的记录 |
set null | 当在父表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null(这就要求该外键允许取null) |
多表查询
多表关系
一对一
案例: 用户 与 用户详情的关系
关系: 一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率
实现: 在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(unique)
一对多
案例: 部门 与 员工的关系
关系: 一个部门对应多个员工,一个员工对应一个部门
实现: 在多的一方建立外键,指向少的一方的主键
多对多
案例: 学生 与 课程的关系
关系: 一个学生可以选修多门课程,一门课程也可以供多个学生选择
实现: 建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
分类
内连接:相当于查询A、B交集部分数据
外连接:
左外连接:查询左表所有数据,以及两张表交集部分数据
右外连接:查询右表所有数据,以及两张表交集部分数据
自连接:当前表与自身的连接查询,自连接必须使用表别名
子查询
内连接
隐式内连接
select 字段列表 from 表1 , 表2 where 条件 … ;
显示内连接
select 字段列表 from 表1 [ inner ] join 表2 on 连接条件 … ;
注意事项
- 当表名过长时,可以给表起别名
- 一旦为表起了别名,就不能再使用表名来指定对应的字段了,此时只能够使用别名来指定字段
外连接
左外连接
select 字段列表 from 表1 left [ outer ] join 表2 on 条件 … ;
右外连接
select 字段列表 from 表1 right [ outer ] join 表2 on 条件 … ;
自连接
select 字段列表 from 表a 别名a join 表a 别名b on 条件 … ;
注意事项
- 在自连接查询中,必须要为表起别名,要不然我们不清楚所指定的条件、返回的字段,到底是哪一张表的字段
- 自连接查询,可以是内连接查询,也可以是外连接查询
联合查询
select 字段列表 from 表a …
union [ all ]
select 字段列表 from 表b …;
注意事项
对于union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集
对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致
union all 会将全部的数据直接合并在一起,union 会对合并之后的数据去重
子查询 (嵌套查询)
select * from t1 where column1 = ( select column1 from t2 );
分类
根据子查询结果不同,分为:
1.标量子查询(子查询结果为单个值)
2.列子查询(子查询结果为一列)
3.行子查询(子查询结果为一行)
4.表子查询(子查询结果为多行多列)
根据子查询位置,分为:
1.where之后
2.from之后
3.select之后
标量子查询
子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式,这种子查询称为标量子查询
常用的操作符:= <> > >= < <=
列子查询
子查询返回的结果是一列(可以是多行),这种子查询称为列子查询
常用的操作符:in 、not in 、 any 、some 、 all
操作符 | 描述 |
---|---|
in | 在指定的集合范围之内,多选一 |
not in | 不在指定的集合范围之内 |
any | 子查询返回列表中,有任意一个满足即可 |
some | 与any等同,使用some的地方都可以使用any |
all | 子查询返回列表的所有值都必须满足 |
行子查询
子查询返回的结果是一行(可以是多列),这种子查询称为行子查询。
常用的操作符:= 、<> 、in 、not in
表子查询
子查询返回的结果是多行多列,这种子查询称为表子查询。
常用的操作符:in