Compare commits

...

2 Commits

  1. 330
      docs/MySQL/mysql是怎样使用的.md
  2. 25
      docs/MySQL/mysql是怎样使用的数据初始化7.0.sql

@ -993,28 +993,358 @@ SELECT CONCAT('学科:', subject), COUNT(student_score.number) AS 人数 FROM st
## 11.2 标量子查询 ## 11.2 标量子查询
- 标量子查询代表的仅仅是一个值 - 标量子查询代表的仅仅是一个值
- 子查询必须用括号括起来
```sql
-- 标量子查询 查名字叫狗哥的人的所有学科成绩
SELECT * FROM student_score WHERE number = (SELECT number FROM student_info WHERE name = '狗哥');
-- 查比狗哥学号大的所有人的信息
SELECT * FROM student_info WHERE number > (SELECT number FROM student_info WHERE name = '狗哥');
```
## 11.3 列子查询
```sql
-- 列子查询 查计算机科学与工程的学生的成绩
SELECT * FROM student_score WHERE number IN (SELECT number FROM student_info WHERE major = '计算机科学与工程');
```
## 11.4 行子查询
- 加入不知道子查询会出现几条记录,加上`LIMIT 1`吧
- 两边均要用括号
```sql
SELECT * FROM student_score WHERE (number, subject) = (SELECT number, 'MySQL是怎样运行的' FROM student_info LIMIT 1);
```
## 11.5 表子查询 (多行多列)
```sql
-- 此版本的MySQL还不支持“LIMIT&IN/ALL/AANY/SOME子查询” MYSQL8.3
SELECT * FROM student_score WHERE (number, subject) IN (SELECT number, 'MySQL是怎样运行的' FROM student_info WHERE major = '计算机科学与工程');
```
## 11.6 `EXISTS``NOT EXISTS`子查询
```sql
-- 如果存在记录就查
SELECT * FROM student_info WHERE EXISTS(SELECT * FROM student_info WHERE number = 10086);
-- 如果不存在记录就查
SELECT * FROM student_info WHERE NOT EXISTS(SELECT * FROM student_info WHERE number = 10086);
-- 相等
SELECT * FROM student_info WHERE (SELECT COUNT(*) FROM student_info WHERE number != 10086) > 1;
```
## 11.7 不相关子查询和相关子查询
- 像上面的,外层查询和子查询不想管,独立运行叫做不相关查询
- 相关查询是,外层查询的值需要被子查询应用,外层查询每查到一行,再拿行数据和子查询进行匹配
```sql
-- 相关子查询 查存在成绩的学生信息
SELECT * FROM student_info a WHERE EXISTS(SELECT number FROM student_score b WHERE a.number = b.number);
-- 显然这个效率很低
SELECT * FROM student_info a WHERE number = IF((SELECT COUNT(number) FROM student_score b WHERE a.number = b.number) > 0, a.number, NULL);
```
## 11.8 对同一个表的子查询
```sql
-- 查大于平均分的成绩
SELECT * FROM student_score WHERE score > (SELECT AVG(score) FROM student_score);
-- 查和狗哥一个学院的人
SELECT * FROM student_info WHERE department = (SELECT department FROM student_info WHERE name = '狗哥');
```
# 第十二章 连接查询
## 12.1 再次认识关系表
- 将两张表合起来的麻烦
- 浪费存储空间
- 维护麻烦,修改信息可能要修改多条数据
## 12.2 连接的概念
- 笛卡尔积
## 12.3 连接查询过滤条件
## 12.4 内连接和外连接
```sql
SELECT * FROM student_info a, student_score b WHERE a.number = b.number;
```
- 内连接:驱动表的数据在被驱动表中不存在,则不会展示出来
- 外连接:即使不存在也展示
- 内连接的ON和WHERE是等价的
### 12.4.1 连接语法
1. 左外连接
用法: `SELECT * FROM t1 LEFT [OUTER] JOIN t2 ON 连接条件 [WHERE 过滤条件]`
- 外连接的ON连接条件不能省略
```sql
SELECT * FROM student_info a LEFT OUTER JOIN student_score b ON a.number = b.number;
```
2. 右外连接
用法: `SELECT * FROM t1 RIGHT [OUTER] JOIN t2 ON 连接条件 [WHERE 过滤条件]`
```sql
SELECT * FROM student_info a RIGHT OUTER JOIN student_score b ON a.number = b.number;
```
### 12.4.2 内连接语法
用法: `SELECT * FROM t1 [INNER | CROSS] JOIN t2 [ON 连接条件] [WHERE 过滤条件]`
等价的:
```sql
SELECT * FROM t1 JOIN t2;
SELECT * FROM t1 INNER JOIN t2; -- 推荐使用
SELECT * FROM t1 CROSS JOIN t2;
SELECT * FROM t1 , t2; -- 这里不能使用ON了,只能用WHERE
```
## 12.5 多表连接
用法: `SELECT * FROM t1 INNER JOIN t2 ON t1.id = t2.id INNER JOIN t3 ON t1.id = t3.id`
`SELECT * FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id = t2.id AND t1.id = t3.id`
- 注意:内连接是取笛卡尔积,所以多张表的连接位置无限制,但是外连接不行,必须明确位置
## 12.6 表的别名
```sql
SELECT t1.id FROM table1 AS t1 ORDER BY DESC t1.id;
SELECT t1.id FROM table1 t1 ORDER BY DESC t1.id;
```
## 自连接
```sql
-- 错误写法
SELECT * FROM t1, t1; -- MYSQL不允许同名,要用别名
SELECT * FROM t1 AS tt1, t1 AS tt2;
-- 自连接,查看和狗哥专业相同的人员信息
SELECT * FROm student_info a JOIN student_info b ON a.major = b.major WHERE a.name = '狗哥';
```
## 12.8 连接查询和子查询的转换
mysql有时候会把子查询在内部转化为连接查询
# 第十三章 并集查询(合并查询、组合查询)
## 13.1 涉及单表的组合查询
```sql
-- 单表组合查询
SELECT name, student_info.department, student_info.major FROM student_info WHERE sex = '男' OR number > 20210101;
SELECT name, student_info.department, student_info.major FROM student_info WHERE sex = '男' UNION SELECT student_info.department, name, student_info.major FROM student_info WHERE number > 20210101;
```
| name | department | major |
| :--- | :--- | :--- |
| 狗哥 | 计算机学院 | 计算机科学与工程 |
| 猫爷 | 计算机学院 | 计算机科学与工程 |
| 亚索 | 计算机学院 | 计算机科学与工程 |
| 赵信 | 航天学院 | 电子信息 |
| 计算机学院 | 猫爷 | 计算机科学与工程 |
| 计算机学院 | 艾希 | 软件工程 |
| 计算机学院 | 亚索 | 计算机科学与工程 |
| 航天学院 | 莫甘娜 | 飞行器设计 |
| 航天学院 | 赵信 | 电子信息 |
- 注意:
- 1. 查询列名类型最好一样,否则mysql会转换
- 2. 查询的列名需要一致,不然是没意义的,或者故意这样做,两个组合查询的查询内容是根据写好的列顺序来组合的,如上表名称和学院位置和第一个语句相反,查出来的内容位置也会错位
- 3. 列名以第一个查询为准
## 13.2 涉及不同表的组合查询
语法和单表一样,使用 `UNION`
## 13.3 包含和去除重复行
- 默认情况下会去掉重复的记录
- 想要保留重复记录使用 `UNION ALL`
## 13.4 组合查询中的 `ORDER BY``LIMIT`
- 最终结果排序,在结尾加就行
- 小查询单独加排序可能无效,加上LIMIT限定有限条数可能可以
# 第十四章 数据的插入、删除和更新
## 14.1 准备工作
```sql
-- 建表
CREATE table first_table(
first_column INT,
second_column VARCHAR(100)
);
```
## 14.2 插入数据
### 14.2.1 插入完整的记录
```sql
-- 不写列明 默认按照建表的顺序 (每列必须明确写出值,可以用NULL替代)
INSERT INTO first_table VALUE (1, '哈哈');
-- 指定列名
INSERT INTO first_table(first_column, second_column) VALUE (2, '嘿嘿');
-- 可以调换列顺序
INSERT INTO first_table(second_column, first_column) VALUE ('嘿嘿嘿', 3);
```
### 14.2.2 插入记录的一部分
- 如果某列有默认值、或者允许为NULL,他就可以不插入,但是要注意插入顺序,如果在中间的话就要指定列名
### 14.2.3 批量插入记录
```sql
-- 批量插入数据 VALUE => VALUES (VALUES也可以只插入一条数据)
INSERT INTO
first_table(second_column, first_column)
VALUE
('嘿哈', 5),
('嗯哼', 6),
('唉嘿', 7),
('嘻嘻', 8),
('呜呜呜', 9);
```
### 14.2.4 将查询的结果插入表中
```sql
-- 插入其他表的数据
INSERT INTO first_table SELECT * FROM first_table LIMIT 4;
INSERT INTO first_table(first_column, second_column) SELECT first_column, second_column FROM first_table WHERE first_column = 3;
```
### 14.2.5 INSERT IGNORE
- 如果存在唯一约束或者主键,插入的数据有冲突的话,单使用INSERT会报错,采用INSERT IGNORE会忽略重复项
### 14.2.6 INSERT ON DUPLICATE KEY UPDATE
如果存在数据,选择更新,我们不需要这样,这样会出现逻辑混乱
## 14.3 删除数据
用法: `DELETE FROM table_name [WHERE 条件]`,不带WHERE条件是不安全的,当前版本会被提示错误;
## 14.4 更新数据
用法: `UPDATE table_name SET 列1=值1, 列2=值2 [WHERE 条件]`
# 第十五章 视图
## 15.1 创建视图
用法: `CREATE VIEW 视图名 AS 查询语句`
## 15.2 使用视图
可以把视图当作一个虚拟表,对正常表的操作,可以用到视图上
### 15.2.1 利用视图创建新的视图
用法和视图创建一样,查询语句作用于原来的视图
### 15.2.2 创建视图时指定自定义列名
用法: `CREATE VIEW 视图名(新列名1, 新列名2) AS SELECT 对应原始列名1, 对应原始列名2 FROM table_name | view_name [查询条件]`
## 15.3 查看和删除视图
### 15.3.1 查看所有视图
`SHOW TABLES;`视图和原始表是在一起的,注意视图创建时,视图名不能和表重名
### 15.3.2 查看视图的定义
`SHOW CREATE VIEW 视图名;`
### 15.3.3 删除视图
`DROP VIEW 视图名;`
## 15.4 可更新视图
如果视图是普通查询语句建立的,不包括汇总,去重,组合,查询中的子查询等,可以直接在视图上更新数据,会映射到真实数据
# 第十六章 存储程序
- 存储例程(存储函数、存储过程)
- 触发器
- 事件
## 16.1 用户自定义变量
定义变量: `SET @变量名 = 值`,可以重新赋值
注意:如果不加`@`符号,mysql会将变量当作系统变量
查看变量: `SELECT @变量名`
将变量复制给变量 `SET @a = @b`,之后再修改b,不会影响a
将查询赋给变量,前提是查询语句的结果是一行一列,可以为NULL
## 16.2 存储函数
用法:
```sql
CREATE FUNCTION 存储函数名称([参数列表])
RETURNS 返回值类型
BEGIN
函数体内容
END
```
### 16.2.1 创建存储函数
```sql
DELIMITER $
CREATE FUNCTION get_score_avg(subject_name VARCHAR(10))
RETURNS DOUBLE
BEGIN
RETURN (SELECT AVG(student_score.score) FROM student_score WHERE subject = subject_name);
END $
DELIMITER ;
```
### 16.2.2 存储函数的调用
```sql
SELECT get_score_avg('计算机是怎样运行的');
```
### 16.2.3 查看和删除存储函数
```sql
-- 查看已经定义的函数和属性
SHOW FUNCTION STATUS [LIKE 函数名的匹配]; -- 不写LIKE会查出来很多函数
-- 查看单个函数
SHOW CREATE FUNCTION 函数名;
-- 删除函数
DROP FUNCTION 函数名;
```

@ -223,3 +223,28 @@ SELECT student_score.subject, COUNT(student_score.number) AS 人数 FROM student
-- 普通连接 和内连接是等价的
SELECT * FROM student_info a, student_score b WHERE a.number = b.number;
-- 左外连接,以a表为基准查出所有
SELECT * FROM student_info a LEFT OUTER JOIN student_score b ON a.number = b.number;
-- 右外连接
SELECT * FROM student_info a RIGHT OUTER JOIN student_score b ON a.number = b.number;
-- 自连接,查看和狗哥专业相同的人员信息
SELECT * FROm student_info a JOIN student_info b ON a.major = b.major WHERE a.name = '狗哥';
-- 单表组合查询
SELECT name, student_info.department, student_info.major FROM student_info WHERE sex = '' OR number > 20210101;
SELECT name, student_info.department, student_info.major FROM student_info WHERE sex = '' UNION SELECT student_info.department, name, student_info.major FROM student_info WHERE number > 20210101;
-- 14章插入建表
CREATE table first_table(
first_column INT,
second_column VARCHAR(100)
);

Loading…
Cancel
Save