前言
重新温习一下MySQL,将以前的知识系统的总结。
扩展
Liunx 全操作过程 【JDK1.8配置、MySQL、Docker、mariaDB、nginx、tomcat、redis、各种问题解决总结】
mysql基础语句
登录mysql
mysql -u root -p 敲回车,输入密码 初始密码查看:cat /var/log/mysqld.log 在root@localhost: 后面的就是初始密码
修改mysql登录密码
set global validate_password_policy=0;
set global validate_password_length=1;
set password=password('密码')
授予远程连接权限
//授权
grant all privileges on *.* to 'root' @'%' identified by '密码';
//刷新
flush privileges;
关闭Linux系统防火墙
systemctl stop firewalld.service
数据库的注释:
- 单行注释:— 注释内容 #注释内容(mysql特有)
- 多行注释:/ 注释内容 /
SQL分类
DDL(Data Definition Language)数据定义语言
用来定义数据库对象:数据库,表,列等。关键字:create, drop,alter 等
DML(Data Manipulation Language)数据操作语言
用来对数据库中表的数据进行增删改。关键字:insert, delete, update 等
DQL(Data Query Language)数据查询语言
用来查询数据库中表的记录(数据)。关键字:select, where 等
DCL(Data Control Language)数据控制语言(了解)
用来定义数据库的访问权限和安全级别,及创建用户。关键字:GRANT, REVOKE 等DDL-操作数据库
```sql — 查询所有数据库 SHOW DATEBASES;
— 查询某个数据库的创建语句 SHOW CREATE DATABASE 数据库名称;
— 查看mysql数据库的创建格式 SHOW CREATE DATABASE mysql;
— 创建数据库 CREATE DATABASE 数据库名称;
— 创建数据库(判断数据库是否存在,不存在则创建) CREATE DATABASE IF NOT EXISTS 数据库名称;
— 创建数据库、并指定字符集 CREATE DATABASE 数据库名称 CHARACTER SET 字符集名称;
— 删除数据库 DROP DATABASE 数据库名称;
— 删除数据库(判断数据库是否存在,如果存在则删除) DROP DATABASE IF EXISTS 数据库名称;
— 查询正在使用的数据库名称 SELECT DATABASE();
— 使用数据库 USE 数据库名称;
<a name="ttgze"></a>
## DDL-操作数据表
```sql
-- 查询数据库中所有的数据表
SHOW TABLES;
-- 查询表结构
DESC 表名;
-- 查询表字符集
SHOW TABLE STATUS FROM 数据库名 LIKE '表名';
-- 创建数据表
CREATE TABLE 表名(
列名1 数据类型1,
列名2 数据类型2,
...
列名n 数据类型n,
);
数据类型
1. int :整数类型
eg :age int -- 年龄
2. double : 小数类型
eg : score double(5,2) -- 成绩
3. date : 日期,只能包含年月日 -- yyyy-MM-dd
4. datetime : 日期,包含年月日时分秒 -- yyyy-MM-dd HH:mm:ss
5. timestamp : 时间戳类型,包含年月日时分秒 -- yyyy-MM-dd HH:mm:ss
注意:时间戳类型可以为空,默认使用当前系统时间
6. varchar : 字符串
eg : name varchar(20)
-- 创建临时数据表(关闭数据库,临时表就不存在)
CREATE TEMPORARY TABLE 表名(
列名1 数据类型1,
列名2 数据类型2,
...
列名n 数据类型n,
);
-- 复制表
CREATE TABLE 表名 LIKE 被复制的表名;
-- 修改表名
ALTER TABLE 表名 RENAME TO 新表名;
-- 添加字段
ALTER TABLE 表名 ADD 列名 数据类型;
-- 修改数据类型
ALTER TABLE 表名 MODIFY 列名 新数据类型;
-- 修改列名和数据类型
ALTER TABLE 表名 CHANGE 列名 新列名 新数据类型;
-- 删除列
ALTER TABLE 表名 DROP 列名;
-- 删除数据表
DROP TABLE 表名;
-- 删除数据表(判断数据表是否存在,存在则删除)
DROP TABLE IF EXISTS 表名;
DML-操作数据表数据
-- 增加数据(对应列名的数据)
INSERT INTO 表名(列名1,列名2,...) VALUES (值1,值2,...);
-- 增加所有的数据
INSERT INTO 表名 VALUES (值1,值2,...);
-- 批量增加数据
INSERT INTO 表名 VALUES (值1,值2,...),(值1,值2,...),(值1,值2,...);
-- 修改数据
UPDATE 表名 SET 列名1 = 值1, 列名2 = 值2, ... [where 条件];
-- 删除数据
DELETE FROM 表名 [where 条件];
DQL-单表查询
-- 查询
select
字段列表
from
表名列表
where
条件列表
group by
分组字段
having
分组之后的条件
order by
排序
limit
分页限定
-- 查询全部
SELECT * FROM 表名;
-- 去除重复查询
SELECT DISTINCT 列名1,列名2,... FROM 表名;
-- 计算列的值(四则运算)
SELECT 列名1 运算符(+ - * /) 列名2 FROM 表名;
-- 查看商品名称,商品库存数量加10
eg : SELECT name,stock+10 FROM product;
-- 查看商品名称,商品库存数量加10,并进行非空判断
eg : SELECT name,IFNULL(stock,0)+10 FROM product;
-- 起别名
SELECT 列名1,列名2,... AS 别名 FROM 表名;
条件查询
符号 | 功能 |
---|---|
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
= | 等于 |
<> 或 != | 不等于 |
BETWEEN … AND … | 在某个范围之内(都包含) |
IN(…) | 多选一 |
LIKE 占位符 | 模糊查询 _单个任意字符 %多个任意字符 |
IS NULL | 是NULL |
IS NOT NULL | 不是NULL |
AND 或 && | 并且 |
OR 或 || | 或者 |
NOT 或 ! | 非,不是 |
例子:
-- 标准语法
SELECT 列名 FROM 表名 WHERE 条件;
-- 查询库存大于20的商品信息
SELECT * FROM product WHERE stock > 20;
-- 查询品牌为华为的商品信息
SELECT * FROM product WHERE brand='华为';
-- 查询金额在4000 ~ 6000之间的商品信息
SELECT * FROM product WHERE price >= 4000 AND price <= 6000;
SELECT * FROM product WHERE price BETWEEN 4000 AND 6000;
-- 查询库存为14、30、23的商品信息
SELECT * FROM product WHERE stock=14 OR stock=30 OR stock=23;
SELECT * FROM product WHERE stock IN(14,30,23);
-- 查询库存为null的商品信息
SELECT * FROM product WHERE stock IS NULL;
-- 查询库存不为null的商品信息
SELECT * FROM product WHERE stock IS NOT NULL;
-- 查询名称以小米为开头的商品信息
SELECT * FROM product WHERE NAME LIKE '小米%';
-- 查询名称第二个字是为的商品信息
SELECT * FROM product WHERE NAME LIKE '_为%';
-- 查询名称为四个字符的商品信息
SELECT * FROM product WHERE NAME LIKE '____';
-- 查询名称中包含电脑的商品信息
SELECT * FROM product WHERE NAME LIKE '%电脑%';
聚合函数
- 将一列数据作为一个整体,进行纵向的计算
- 聚合函数分类
函数名 | 功能 |
---|---|
count(列名) | 统计数量(一般选用不为null的列) |
max(列名) | 最大值 |
min(列名) | 最小值 |
sum(列名) | 求和 |
avg(列名) | 平均值 |
-- 标准语法
SELECT 函数名(列名) FROM 表名 [WHERE 条件];
-- 计算product表中总记录条数
SELECT COUNT(*) FROM product;
-- 获取最高价格
SELECT MAX(price) FROM product;
-- 获取最高价格的商品名称
SELECT NAME,price FROM product WHERE price = (SELECT MAX(price) FROM product);
-- 获取最低库存
SELECT MIN(stock) FROM product;
-- 获取最低库存的商品名称
SELECT NAME,stock FROM product WHERE stock = (SELECT MIN(stock) FROM product);
-- 获取总库存数量
SELECT SUM(stock) FROM product;
-- 获取品牌为苹果的总库存数量
SELECT SUM(stock) FROM product WHERE brand='苹果';
-- 获取品牌为小米的平均商品价格
SELECT AVG(price) FROM product WHERE brand='小米';
排序查询
注意:多个排序条件,当前边的条件值一样时,才会判断第二条件
-- 排序
SELECT 列名 FROM 表名 [WHERE 条件] ORDER BY 列名1 排序方式1,列名2 排序方式2;
-- 按照库存升序排序
SELECT * FROM product ORDER BY stock ASC;
-- 查询名称中包含手机的商品信息。按照金额降序排序
SELECT * FROM product WHERE NAME LIKE '%手机%' ORDER BY price DESC;
-- 按照金额升序排序,如果金额相同,按照库存降序排列
SELECT * FROM product ORDER BY price ASC,stock DESC;
分组查询
-- 标准语法
SELECT 列名 FROM 表名 [WHERE 条件] GROUP BY 分组列名 [HAVING 分组后条件过滤] [ORDER BY 排序列名 排序方式];
-- 按照品牌分组,获取每组商品的总金额
SELECT brand,SUM(price) FROM product GROUP BY brand;
-- 对金额大于4000元的商品,按照品牌分组,获取每组商品的总金额
SELECT brand,SUM(price) FROM product WHERE price > 4000 GROUP BY brand;
-- 对金额大于4000元的商品,按照品牌分组,获取每组商品的总金额,只显示总金额大于7000元的
SELECT brand,SUM(price) AS getSum FROM product WHERE price > 4000 GROUP BY brand HAVING getSum > 7000;
-- 对金额大于4000元的商品,按照品牌分组,获取每组商品的总金额,只显示总金额大于7000元的、并按照总金额的降序排列
SELECT brand,SUM(price) AS getSum FROM product WHERE price > 4000 GROUP BY brand HAVING getSum > 7000 ORDER BY getSum DESC;
分页查询
-- 标准语法
SELECT 列名 FROM 表名 [WHERE 条件] GROUP BY 分组列名 [HAVING 分组后条件过滤] [ORDER BY 排序列名 排序方式] LIMIT 开始索引,查询条数;
-- 公式:开始索引 = (当前页码-1) * 每页显示的条数
-- 每页显示2条数据
SELECT * FROM product LIMIT 0,2; -- 第一页 开始索引=(1-1) * 2
SELECT * FROM product LIMIT 2,2; -- 第二页 开始索引=(2-1) * 2
SELECT * FROM product LIMIT 4,2; -- 第三页 开始索引=(3-1) * 2
SELECT * FROM product LIMIT 6,2; -- 第四页 开始索引=(4-1) * 2
外键
约束的概念
- 对表中的数据进行限定,保证数据的正确性、有效性、完整性!
约束的分类
| 约束 | 说明 | | —- | —- | | PRIMARY KEY | 主键约束 | | PRIMARY KEY AUTO_INCREMENT | 主键、自动增长 | | UNIQUE | 唯一约束 | | NOT NULL | 非空约束 | | FOREIGN KEY | 外键约束 | | FOREIGN KEY ON UPDATE CASCADE | 外键级联更新 | | FOREIGN KEY ON DELETE CASCADE | 外键级联删除 |
主键约束
-- 建表时添加主键约束
CREATE TABLE 表名(
列名 数据类型 PRIMARY KEY,
列名 数据类型,
...
);
-- 创建student表
CREATE TABLE student(
id INT PRIMARY KEY -- 给id添加主键约束
);
-- 添加数据
INSERT INTO student VALUES (1),(2);
-- 主键默认唯一,添加重复数据,会报错
INSERT INTO student VALUES (2);
-- 主键默认非空,不能添加null的数据
INSERT INTO student VALUES (NULL);
-- 删除主键
ALTER TABLE 表名 DROP PRIMARY KEY;
-- 建表后单独添加主键
ALTER TABLE 表名 MODIFY 列名 数据类型 PRIMARY KEY;
主键自动增长约束
-- 建表时添加主键自增约束
CREATE TABLE 表名(
列名 数据类型 PRIMARY KEY AUTO_INCREMENT,
列名 数据类型,
...
);
-- 创建student2表
CREATE TABLE student2(
id INT PRIMARY KEY AUTO_INCREMENT -- 给id添加主键自增约束
);
-- 添加数据
INSERT INTO student2 VALUES (1),(2);
-- 添加null值,会自动增长
INSERT INTO student2 VALUES (NULL),(NULL);
-- 删除自动增长
ALTER TABLE 表名 MODIFY 列名 数据类型;
-- 建表后单独添加自动增长
ALTER TABLE 表名 MODIFY 列名 数据类型 AUTO_INCREMENT;
唯一约束
-- 建表时添加唯一约束
CREATE TABLE 表名(
列名 数据类型 UNIQUE,
列名 数据类型,
...
);
-- 创建student3表
CREATE TABLE student3(
id INT PRIMARY KEY AUTO_INCREMENT,
tel VARCHAR(20) UNIQUE -- 给tel列添加唯一约束
);
-- 添加数据
INSERT INTO student3 VALUES (NULL,'18888888888'),(NULL,'18666666666');
-- 添加重复数据,会报错
INSERT INTO student3 VALUES (NULL,'18666666666');
-- 删除唯一约束
ALTER TABLE 表名 DROP INDEX 列名;
-- 建表后单独添加唯一约束
ALTER TABLE 表名 MODIFY 列名 数据类型 UNIQUE;
非空约束
-- 建表时添加非空约束
CREATE TABLE 表名(
列名 数据类型 NOT NULL,
列名 数据类型,
...
);
-- 创建student4表
CREATE TABLE student4(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20) NOT NULL -- 给name添加非空约束
);
-- 添加数据
INSERT INTO student4 VALUES (NULL,'张三'),(NULL,'李四');
-- 添加null值,会报错
INSERT INTO student4 VALUES (NULL,NULL);
-- 删除非空约束
ALTER TABLE 表名 MODIFY 列名 数据类型;
-- 建表后单独添加非空约束
ALTER TABLE 表名 MODIFY 列名 数据类型 NOT NULL;
外键约束
-- 建表时添加外键约束
CONSTRAINT 外键名 FOREIGN KEY (本表外键列名) REFERENCES 主表名(主表主键列名)
CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT, -- id
NAME VARCHAR(20) NOT NULL -- 姓名
);
-- 添加用户数据
INSERT INTO USER VALUES (NULL,'张三'),(NULL,'李四'),(NULL,'王五');
-- 创建order订单表
CREATE TABLE order(
id INT PRIMARY KEY AUTO_INCREMENT, -- id
number VARCHAR(20) NOT NULL, -- 订单编号
uid INT, -- 订单所属用户
CONSTRAINT user_order FOREIGN KEY (uid) REFERENCES USER(id) -- 添加外键约束
);
-- 添加订单数据
INSERT INTO orderlist VALUES (NULL,'hm001',1),(NULL,'hm002',1);
-- 添加一个订单,但是没有所属用户。无法添加
INSERT INTO orderlist VALUES (NULL,'hm007',8);
-- 删除王五这个用户,但是订单表中王五还有很多个订单呢。无法删除
DELETE FROM USER WHERE NAME='王五';
-- 删除外键约束
ALTER TABLE 表名 DROP FOREIGN KEY 外键名;
-- 建表后添加外键约束
ALTER TABLE 表名 ADD CONSTRAINT 外键名 FOREIGN KEY (本表外键列名) REFERENCES 主表名(主键列名);
外键的级联更新和级联删除
什么是级联更新和级联删除
- 当我想把user用户表中的某个用户删掉,我希望该用户所有的订单也随之被删除
- 当我想把user用户表中的某个用户id修改,我希望订单表中该用户所属的订单用户编号也随之修改
```sql — 添加外键约束,同时添加级联更新 标准语法 ALTER TABLE 表名 ADD CONSTRAINT 外键名 FOREIGN KEY (本表外键列名) REFERENCES 主表名(主键列名) ON UPDATE CASCADE;
— 添加外键约束,同时添加级联删除 标准语法 ALTER TABLE 表名 ADD CONSTRAINT 外键名 FOREIGN KEY (本表外键列名) REFERENCES 主表名(主键列名) ON DELETE CASCADE;
— 添加外键约束,同时添加级联更新和级联删除 标准语法 ALTER TABLE 表名 ADD CONSTRAINT 外键名 FOREIGN KEY (本表外键列名) REFERENCES 主表名(主键列名) ON UPDATE CASCADE ON DELETE CASCADE;
— 删除外键约束 ALTER TABLE orderlist DROP FOREIGN KEY user_order;
— 添加外键约束,同时添加级联更新和级联删除 ALTER TABLE orderlist ADD CONSTRAINT user_order FOREIGN KEY (uid) REFERENCES USER(id) ON UPDATE CASCADE ON DELETE CASCADE;
— 将王五用户的id修改为5 订单表中的uid也随之被修改 UPDATE USER SET id=5 WHERE id=3;
— 将王五用户删除 订单表中该用户所有订单也随之删除 DELETE FROM USER WHERE id=5;
<a name="NaYo5"></a>
## 多表设计
<a name="K25Cd"></a>
### 一对一
**业务**<br />人和身份证。一个人只有一个身份证,一个身份证只能对应一个人!<br />**实现原则**<br />在任意一个表建立外键,去关联另外一个表的主键<br />**示意图**<br /><br />**增删改查的影响范围**<br />**增**:数据可以不分先后顺序增加,也不需要必要的对应关系,一个人没有身份证的数据也是可以存在,一个无效身份证的数据也是可以存在。<br />在业务角度上讲,需要程序员严谨的增加一对一的数据,不然会产生脏数据。<br />**删**:数据可以任意删除,没有任何限制。<br />**改**:两张表的数据可以任意修改,将约束外键修改其他值,也没有任何限制。<br />当程序想要进行修改,那么一定不能直接操作外键约束,最好只操作对应的信息。<br />**查**:查询两张表的数据,当使用内连接时,可以查出一对一的关系,建议使用。<br />当使用左连接时,根据左侧表为主体,查询出左侧表的全部数据,右侧表中有对应关系的数据才会查出,反之全部null值显示。<br />当使用右连接时,与上面相反,以右侧表为主体。<br />当使用合并连接时,会将重复的数据排除掉。<br />当使用子查询时,可以查询出脏数据。
```sql
-- 创建db5数据库
CREATE DATABASE db5 CHARACTER SET utf8;
-- 使用db5数据库
USE db5;
-- 创建person表
CREATE TABLE person(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
)ENGINE = InnoDB DEFAULT CHARSET = utf8;
-- 添加数据
INSERT INTO person VALUES (NULL,'张三'),(NULL,'李四');
-- 创建card表
CREATE TABLE card(
id INT PRIMARY KEY AUTO_INCREMENT,
number VARCHAR(50),
pid INT UNIQUE,
CONSTRAINT cp_fk1 FOREIGN KEY (pid) REFERENCES person(id) -- 添加外键
)ENGINE = InnoDB DEFAULT CHARSET = utf8;
-- 添加数据
INSERT INTO card VALUES (NULL,'12345',1),(NULL,'56789',3);
-- 查询还没有身份证的公民
select * from person where id not in (select pid from card);
+----+------+
| id | NAME |
+----+------+
| 2 | 李四 |
+----+------+
1 row in set
-- 查询有身份证的公民
select * from person join card on person.id = card.pid;
+----+------+----+--------+-----+
| id | NAME | id | number | pid |
+----+------+----+--------+-----+
| 1 | 张三 | 1 | 12345 | 1 |
+----+------+----+--------+-----+
1 row in set
一对多
业务
用户和订单。一个用户可以有多个订单!
实现原则
在多的一方,建立外键约束,来关联一的一方主键
示意图
增删改查的影响范围
增:增加两张表的数据,可以任意增加数据,但是不建议没有先创建主表数据,按照一对多原则,必须有一才能有多的关系。多则可以不用创建。
删:可以随便删除数据,但是不允许删除主表数据。
改:不可以修改两张表任意的外键约束,但是可以修改业务数据。
查:内连接和左连接都可以查询出一对多关联的数据,右连接会查询出没有一对多关联的数据,也会查询出一对多关联的数据。根据业务进行选择使用那种方式。
/*
用户和订单
*/
-- 创建user表
CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
)ENGINE = InnoDB DEFAULT CHARSET = utf8;
-- 添加数据
INSERT INTO USER VALUES (NULL,'张三'),(NULL,'李四');
-- 创建orderlist表
CREATE TABLE orderlist(
id INT PRIMARY KEY AUTO_INCREMENT,
number VARCHAR(20),
uid INT,
CONSTRAINT ou_fk1 FOREIGN KEY (uid) REFERENCES USER(id) -- 添加外键约束
)ENGINE = InnoDB DEFAULT CHARSET = utf8;
-- 添加数据
INSERT INTO orderlist VALUES (NULL,'hm001',1),(NULL,'hm002',1),(NULL,'hm003',2),(NULL,'hm004',2);
多对多
业务
学生和课程。一个学生可以选择多个课程,一个课程也可以被多个学生选择!
实现原则
需要借助第三张表中间表,中间表至少包含两个列,这两个列作为中间表的外键,分别关联两张表的主键
示意图
增删改查的影响范围
增:除了中间表建立联系,另外两张表可以任意增加数据,中间表也可以随便增加数据,但是在业务中不允许出现中间表,胡乱增加不存在的关系,增加脏数据的存在。
删:可以删除这三张表的所有数据,根据实际业务判断。
改:可以随意修改这三张表的数据,包括外键约束都可以修改,按照实际业务中,外键约束不能进行随意修改。
查:
-- 创建student表
CREATE TABLE student(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
);
-- 添加数据
INSERT INTO student VALUES (NULL,'张三'),(NULL,'李四');
-- 创建course表
CREATE TABLE course(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10)
);
-- 添加数据
INSERT INTO course VALUES (NULL,'语文'),(NULL,'数学');
-- 创建中间表
CREATE TABLE stu_course(
id INT PRIMARY KEY AUTO_INCREMENT,
sid INT, -- 用于和student表的id进行外键关联
cid INT, -- 用于和course表的id进行外键关联
CONSTRAINT sc_fk1 FOREIGN KEY (sid) REFERENCES student(id), -- 添加外键约束
CONSTRAINT sc_fk2 FOREIGN KEY (cid) REFERENCES course(id) -- 添加外键约束
);
-- 添加数据
INSERT INTO stu_course VALUES (NULL,1,1),(NULL,6,2),(NULL,2,1),(NULL,2,2);
-- 子查询
select * from (select * from student ) s ,(select * from stu_course) sc,(select * from course) c where s.id=sc.sid and c.id = sc.cid;
+----+------+----+-----+-----+----+------+
| id | NAME | id | sid | cid | id | NAME |
+----+------+----+-----+-----+----+------+
| 1 | 张三 | 1 | 1 | 1 | 1 | 语文 |
| 2 | 李四 | 3 | 2 | 1 | 1 | 语文 |
| 2 | 李四 | 4 | 2 | 2 | 2 | 数学 |
+----+------+----+-----+-----+----+------+
3 rows in set
-- 内连接
select * from student s join stu_course sc on sc.sid = s.id join course c on sc.cid = c.id;
+----+------+----+-----+-----+----+------+
| id | NAME | id | sid | cid | id | NAME |
+----+------+----+-----+-----+----+------+
| 1 | 张三 | 1 | 1 | 1 | 1 | 语文 |
| 2 | 李四 | 3 | 2 | 1 | 1 | 语文 |
| 2 | 李四 | 4 | 2 | 2 | 2 | 数学 |
+----+------+----+-----+-----+----+------+
3 rows in set
-- 左连接
select * from student s left join stu_course sc on sc.sid = s.id left
join course c on sc.cid = c.id;
+----+------+------+------+------+------+------+
| id | NAME | id | sid | cid | id | NAME |
+----+------+------+------+------+------+------+
| 1 | 张三 | 1 | 1 | 1 | 1 | 语文 |
| 2 | 李四 | 3 | 2 | 1 | 1 | 语文 |
| 2 | 李四 | 4 | 2 | 2 | 2 | 数学 |
| 3 | 王五 | NULL | NULL | NULL | NULL | NULL |
+----+------+------+------+------+------+------+
4 rows in set
-- 右连接
select * from student s right join
stu_course sc on sc.sid = s.id right join course c on sc.cid = c.id;
+------+------+------+------+------+----+------+
| id | NAME | id | sid | cid | id | NAME |
+------+------+------+------+------+----+------+
| 1 | 张三 | 1 | 1 | 1 | 1 | 语文 |
| 2 | 李四 | 3 | 2 | 1 | 1 | 语文 |
| NULL | NULL | 2 | 6 | 2 | 2 | 数学 |
| 2 | 李四 | 4 | 2 | 2 | 2 | 数学 |
| NULL | NULL | NULL | NULL | NULL | 3 | 英语 |
+------+------+------+------+------+----+------+
5 rows in set
多表查询
-- 笛卡尔积查询
SELECT 列名 FROM 表名1,表名2,...;
-- 内连接查询[内连接查询的是两张表有交集的部分数据(有主外键关联的数据)]
SELECT 列名 FROM 表名1 [INNER] JOIN 表名2 ON 条件;
-- 隐式内连接
SELECT 列名 FROM 表名1,表名2 WHERE 条件;
-- 外连接查询[查询左表的全部数据,和左右两张表有交集部分的数据]
SELECT 列名 FROM 表名1 LEFT [OUTER] JOIN 表名2 ON 条件;
-- 右外连接[查询右表的全部数据,和左右两张表有交集部分的数据]
SELECT 列名 FROM 表名1 RIGHT [OUTER] JOIN 表名2 ON 条件;
-- 子查询[查询语句中嵌套了查询语句。我们就将嵌套查询称为子查询!]
-- 子查询-结果是单行单列
SELECT 列名 FROM 表名 WHERE 列名=(SELECT 聚合函数(列名) FROM 表名 [WHERE 条件]);
-- 子查询-结果是多行单列
SELECT 列名 FROM 表名 WHERE 列名 [NOT] IN (SELECT 列名 FROM 表名 [WHERE 条件]);
-- 子查询-结果是多行多列
SELECT 列名 FROM 表名 [别名],(SELECT 列名 FROM 表名 [WHERE 条件]) [别名] [WHERE 条件];