MySQL知识大总结(进阶)

一,数据库的约束

1,约束类型

|---|-------------|---------------------------------------------|
| 1 | not null | 非空约束,标记这个字段不可以为空 |
| 2 | unique | 唯一约束,标记这个字段的值是该列唯一的值,在这一列的其他行,不可以与该字段相等 |
| 3 | default | 默认约束,在该字段没有赋值时,使用默认值填充该列 |
| 4 | primary key | 主键约束,相当于not null + unique |
| 5 | foreign key | 外键约束,与其他表的主键简历联系,在添加或修改数据是,会根据主外键关系检查数据是否合法 |

1,not null

试着使用not null 来创建数据表

sql 复制代码
create table if not exists student(
    -> id bigint not null,
    -> name varchar(20) not null
    -> );
sql 复制代码
 desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | bigint      | NO   |     | NULL    |       |
| name  | varchar(20) | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

我们看到在null的列,两个字段都不允许为空,我们添加两行不为空和一行为空的数据来试一下。

sql 复制代码
insert into student values (1,'张三'),(2,'李四');
sql 复制代码
select * from student;
+----+--------+
| id | name   |
+----+--------+
|  1 | 张三   |
|  2 | 李四   |
+----+--------+

成功添加

sql 复制代码
insert into student values (null,null);
ERROR 1048 (23000): Column 'id' cannot be null

在新增数据发生报错,它不允许字段id为空。

2,unique

在试着用unique来创建一个表

sql 复制代码
create table if not exists student(
    -> id bigint unique,
    -> name varchar(20) unique
    -> );
sql 复制代码
desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | bigint      | YES  | UNI | NULL    |       |
| name  | varchar(20) | YES  | UNI | NULL    |       |
+-------+-------------+------+-----+---------+-------+

key 变成了唯一类型

我们添加三个数据,两个相同的,一个不同的

sql 复制代码
insert into student values (1,'张三'),(2,'李四');
Query OK, 2 rows affected (0.00 sec)

成功添加了,

sql 复制代码
insert into student values (1,'王五');
ERROR 1062 (23000): Duplicate entry '1' for key 'student.id'
sql 复制代码
 insert into student values (3,'张三');
ERROR 1062 (23000): Duplicate entry '张三' for key 'student.name'

两个字段都设置为唯一类型的,所以无论哪一个字段重复了都不可以。

3,default

sql 复制代码
 create table if not exists student(
    -> id bigint default 0,
    -> name varchar(20) default '无名氏' unique
    -> );

这些数据库约束是可以一起使用的,

sql 复制代码
desc student;
+-------+-------------+------+-----+-----------+-------+
| Field | Type        | Null | Key | Default   | Extra |
+-------+-------------+------+-----+-----------+-------+
| id    | bigint      | YES  |     | 0         |       |
| name  | varchar(20) | YES  | UNI | 无名氏    |       |
+-------+-------------+------+-----+-----------+-------+

我们来添加两个啥都没有的数据

sql 复制代码
insert into student (id) values (1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into student (name) values ('张三');
Query OK, 1 row affected (0.00 sec)
sql 复制代码
select * from student;
+------+-----------+
| id   | name      |
+------+-----------+
|    1 | 无名氏    |
|    0 | 张三      |
+------+-----------+

空缺的元素都由默认值填补了。

4,primary key

可以使用auto_increment来在主键后面,这样就代表这个字段是自增主键,不用对其进行赋值,在其他列的插入时,就会自行生成对应的id,但是如果我们这行sql语句写错了的话id是不会接着上一行数据的id继续的,

sql 复制代码
 create table if not exists student(
    -> id bigint primary key auto_increment,
    -> name varchar(20)
    -> );

复合主键

sql 复制代码
create table if not exists student(
    -> id bigint,
    -> name varchar(20),
    -> primary key(id,name)
    -> );
sql 复制代码
desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | bigint      | NO   | PRI | NULL    |       |
| name  | varchar(20) | NO   | PRI | NULL    |       |
+-------+-------------+------+-----+---------+-------+

5,foreign key

sql 复制代码
create table if not exists student(
    -> id bigint primary key auto_increment,
    -> name varchar(20),
    -> class_id bigint,
    -> foreign key (class_id) references class(id)
    -> );
sql 复制代码
desc student;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | bigint      | NO   | PRI | NULL    | auto_increment |
| name     | varchar(20) | YES  |     | NULL    |                |
| class_id | bigint      | YES  | MUL | NULL    |                |
+----------+-------------+------+-----+---------+----------------+

有了外键到约束我们就不能随便插入数据了

sql 复制代码
select * from class;
+----+---------+
| id | name    |
+----+---------+
|  1 | java113 |
|  2 | java112 |
|  3 | java111 |
+----+---------+

我们班级表新增三个班级

sql 复制代码
select * from student;
+----+--------+----------+
| id | name   | class_id |
+----+--------+----------+
|  1 | 张三   |        1 |
|  2 | 李四   |        2 |
|  3 | 王五   |        3 |
+----+--------+----------+

再给每个班级新增一个学生

我们再试着给学生表中添加一个4班的学生,但是班级表是不存在编号为4的班级的

sql 复制代码
insert into student (name,class_id) values ('张三','4');
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`java113`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`))

因为外键约束,我们无法添加class表中没有的班级的学生编号

二,表的设计

1,三大范式

1,第一范式:要求表中的每一列不可再分,其实就是数据库提供的数据类型能描述这个字段,如果不满足第一范式,那么数据库就不是关系型数据库

2,第二范式:在满足第一范式的基础上,消除部分函数依赖,只能出现在有复合主键的表上,如果有一列字段只依赖于复合主键的其中一列,就需要移除这个列,单独建表。如果不满足第二范式就会出现删除异常,新增异常,更新异常,数据冗余

3,第三范式:在第二范式的基础上,消除传递依赖,这个是如果除主键外的某一列,对其他某一列存在依赖时,我们就要移除这个列

2,关系模型

1,一对一模型:

各自建立各自的表,在一个表中添加一个字段完成对另一个表的引用。

2,一对多模型:

各自建立各自的表,在一表中设置主键,在多表中设置外键于一表主键关联。

3,多对多模型:

各自建立各自的表,另外添加一个新的关系表。

我们举个多对多模型的例子,

一个class表

sql 复制代码
> create table if not exists class (
    -> id bigint primary key auto_increment,
    -> name varchar(20)
    -> );

一个student表

sql 复制代码
create table if not exists student(
    -> id bigint primary key auto_increment,
    -> name varchar(20)
    -> );

一个sorce表来关联这两个表

sql 复制代码
 create table if not exists sorce(
    -> id bigint primary key auto_increment,
    -> student_id bigint,
    -> class_id bigint,
    -> stu_score decimal(3,1),
    -> foreign key (student_id) references student(id),
    -> foreign key (class_id) references class(id)
    -> );

这就形成了多对多关系

三,查询(进阶)

1,插入时查询

语法:

insert into 新表名 (列名) select 要复制的列名(这里不要使用括号)from 旧表名

这个我们可以用到表复制的时候

sql 复制代码
select * from student;
+----+---------+
| id | name    |
+----+---------+
|  1 | 张三    |
|  2 | 0李四   |
|  3 | 王五    |
+----+---------+

我们现在创建一个新表,直接将旧表的数据复制到新表中

sql 复制代码
 create table if not exists new_student(
    -> id bigint primary key auto_increment,
    -> name varchar(20)
    -> );
sql 复制代码
 insert into new_student (id,name) select id,name from student;

2,聚合函数

sql 复制代码
select * from course;
+-----------+--------------------+
| course_id | name               |
+-----------+--------------------+
|         1 | Java               |
|         2 | 中国传统文化       |
|         3 | 计算机原理         |
|         4 | 语文               |
|         5 | 高阶数学           |
|         6 | 英文               |
+-----------+--------------------+
sql 复制代码
 select * from class;
+----------+-------------------------+
| class_id | name                    |
+----------+-------------------------+
|        1 | 计算机系2019级1班       |
|        2 | 中文系2019级3班         |
|        3 | 自动化2019级5班         |
+----------+-------------------------+
sql 复制代码
 select * from student;
+------------+-------+-----------------+------------------+----------+
| student_id | sn    | name            | mail             | class_id |
+------------+-------+-----------------+------------------+----------+
|          1 | 09982 | 黑旋风李逵      | xuanfeng@qq.com  |        1 |
|          2 | 00835 | 菩提老祖        | NULL             |        1 |
|          3 | 00391 | 白素贞          | NULL             |        1 |
|          4 | 00031 | 许仙            | xuxian@qq.com    |        1 |
|          5 | 00054 | 不想毕业        | NULL             |        1 |
|          6 | 51234 | 好好说话        | say@qq.com       |        2 |
|          7 | 83223 | tellme          | NULL             |        2 |
|          8 | 09527 | 老外学中文      | foreigner@qq.com |        2 |
+------------+-------+-----------------+------------------+----------+
sql 复制代码
 select * from exam;
+------+-----------+---------+------+---------+
| id   | name      | chinese | math | english |
+------+-----------+---------+------+---------+
|    1 | 唐三藏    |    67.0 | 98.0 |    56.0 |
|    2 | 孙悟空    |    87.5 | 78.0 |    77.0 |
|    3 | 猪悟能    |    88.0 | 98.0 |    90.0 |
|    4 | 曹孟德    |    82.0 | 84.0 |    67.0 |
|    5 | 刘玄德    |    55.5 | 85.0 |    45.0 |
|    6 | 孙权      |    70.0 | 73.0 |    78.5 |
|    7 | 宋公明    |    75.0 | 65.0 |    30.0 |
+------+-----------+---------+------+---------+
sql 复制代码
mysql> select * from emp;
+----+-----------+--------------+------------+
| id | name      | role         | salary     |
+----+-----------+--------------+------------+
|  1 | 马云      | 老板         | 1500000.00 |
|  2 | 马化腾    | 老板         | 1800000.00 |
|  3 | 鑫哥      | 讲师         |   10000.00 |
|  4 | 博哥      | 讲师         |   12000.00 |
|  5 | 平姐      | 学管         |    9000.00 |
|  6 | 莹姐      | 学管         |    8000.00 |
|  7 | 猪悟能    | 游戏角色     |     700.50 |
|  8 | 沙和尚    | 游戏角色     |     333.30 |
+----+-----------+--------------+------------+
sql 复制代码
select * from score;
+----------+------------+-----------+-------+
| score_id | student_id | course_id | score |
+----------+------------+-----------+-------+
|        1 |          1 |         1 | 70.50 |
|        2 |          1 |         3 | 98.50 |
|        3 |          1 |         5 | 33.00 |
|        4 |          1 |         6 | 98.00 |
|        5 |          2 |         1 | 60.00 |
|        6 |          2 |         5 | 59.50 |
|        7 |          3 |         1 | 33.00 |
|        8 |          3 |         3 | 68.00 |
|        9 |          3 |         5 | 99.00 |
|       10 |          4 |         1 | 67.00 |
|       11 |          4 |         3 | 23.00 |
|       12 |          4 |         5 | 56.00 |
|       13 |          4 |         6 | 72.00 |
|       14 |          5 |         1 | 81.00 |
|       15 |          5 |         5 | 37.00 |
|       16 |          6 |         2 | 56.00 |
|       17 |          6 |         4 | 43.00 |
|       18 |          6 |         6 | 79.00 |
|       19 |          7 |         2 | 80.00 |
|       20 |          7 |         6 | 92.00 |
+----------+------------+-----------+-------+

我们拿这几个表来举例子。

1,count(列):统计一列的个数

------------1,统计班级有多少同学

sql 复制代码
select count(*) from exam;
+----------+
| count(*) |
+----------+
|        7 |
+----------+

------------2,统计班级收集的 qq_mail 有多少个,qq_mail 为 NULL 的数据不会计入结果

sql 复制代码
 select count(mail) from student
    -> ;
+-------------+
| count(mail) |
+-------------+
|           4 |
+-------------+

2,Sum(列):求和

------------1,统计数学成绩总分

sql 复制代码
select sum(math) from exam;
+-----------+
| sum(math) |
+-----------+
|     581.0 |
+-----------+

------------2,不及格 < 60 的总分,没有结果,返回 NULL

sql 复制代码
select sum(math) from exam where math<60;
+-----------+
| sum(math) |
+-----------+
|      NULL |
+-----------+

3,AVG(列):求平均值

------------1,统计平均总分

sql 复制代码
 select avg(english) from exam;
+--------------+
| avg(english) |
+--------------+
|     63.35714 |
+--------------+

4,MAX(列):求最大值

------------1,返回英语最高分

sql 复制代码
 select max(english) from exam;
+--------------+
| max(english) |
+--------------+
|         90.0 |
+--------------+

5,MIN(列):求最小值

------------1,返回 > 70 分以上的数学最低分

sql 复制代码
select min(math) from exam where math>70;
+-----------+
| min(math) |
+-----------+
|      73.0 |
+-----------+

3,group by

group by 语句就是分组查询

语法:

select 字段1 字段2 from 表名 group by 字段1 ,字段2;

group by是可以使用别名的,但是where不行

sql 复制代码
select * from emp;
+----+-----------+--------------+------------+
| id | name      | role         | salary     |
+----+-----------+--------------+------------+
|  1 | 马云      | 老板         | 1500000.00 |
|  2 | 马化腾    | 老板         | 1800000.00 |
|  3 | 鑫哥      | 讲师         |   10000.00 |
|  4 | 博哥      | 讲师         |   12000.00 |
|  5 | 平姐      | 学管         |    9000.00 |
|  6 | 莹姐      | 学管         |    8000.00 |
|  7 | 猪悟能    | 游戏角色     |     700.50 |
|  8 | 沙和尚    | 游戏角色     |     333.30 |
+----+-----------+--------------+------------+

我们使用这个表

------------1,查询每个角色的最高工资、最低工资和平均工资

sql 复制代码
select role,max(salary),min(salary),avg(salary) from emp group by role;
+--------------+-------------+-------------+----------------+
| role         | max(salary) | min(salary) | avg(salary)    |
+--------------+-------------+-------------+----------------+
| 老板         |  1800000.00 |  1500000.00 | 1650000.000000 |
| 讲师         |    12000.00 |    10000.00 |   11000.000000 |
| 学管         |     9000.00 |     8000.00 |    8500.000000 |
| 游戏角色     |      700.50 |      333.30 |     516.900000 |
+--------------+-------------+-------------+----------------+

4,Having

我们使用group by 的时候不能使用where字句,所以出现了Having,我们使用Having来过滤条件;

------------1,显示平均工资低于1500的角色和它的平均工资

sql 复制代码
select role,avg(salary) from emp group by role having avg(salary)<1500;
+--------------+-------------+
| role         | avg(salary) |
+--------------+-------------+
| 游戏角色     |  516.900000 |
+--------------+-------------+

5,联合查询

对多张表进行取笛卡尔积,在选取正确的联合表;

1,内连接

语法:

select 表1 别名,表2 别名 where 连接条件 and 其他条件

select 表1 别名 [inner] join 表2 别名2 on 连接条件 and 其他条件

------------1,查询"许仙"同学的 成绩

sql 复制代码
 select stu.name,sc.score from student stu,score sc where sc.student_id = stu.student_id and stu.name = '许仙';
+--------+-------+
| name   | score |
+--------+-------+
| 许仙   | 67.00 |
| 许仙   | 23.00 |
| 许仙   | 56.00 |
| 许仙   | 72.00 |
+--------+-------+
sql 复制代码
 select stu.name,sc.score from student stu inner join score sc on stu.student_id = sc.student_id where stu.name = '许仙';
+--------+-------+
| name   | score |
+--------+-------+
| 许仙   | 67.00 |
| 许仙   | 23.00 |
| 许仙   | 56.00 |
| 许仙   | 72.00 |
+--------+-------+

------------2,查询所有同学的总成绩,及同学的个人信息:

sql 复制代码
select stu.name,stu.sn,stu.mail,sum(sc.score) from student stu,score sc where stu.student_id = sc.student_id group by stu.student_id;
+-----------------+-------+-----------------+---------------+
| name            | sn    | mail            | sum(sc.score) |
+-----------------+-------+-----------------+---------------+
| 黑旋风李逵      | 09982 | xuanfeng@qq.com |        300.00 |
| 菩提老祖        | 00835 | NULL            |        119.50 |
| 白素贞          | 00391 | NULL            |        200.00 |
| 许仙            | 00031 | xuxian@qq.com   |        218.00 |
| 不想毕业        | 00054 | NULL            |        118.00 |
| 好好说话        | 51234 | say@qq.com      |        178.00 |
| tellme          | 83223 | NULL            |        172.00 |
+-----------------+-------+-----------------+---------------+
sql 复制代码
select stu.sn,stu.name,stu.mail,sum(sc.score) from student stu inner join score sc on stu.student_id = sc.student_id group by stu.student_id;
+-------+-----------------+-----------------+---------------+
| sn    | name            | mail            | sum(sc.score) |
+-------+-----------------+-----------------+---------------+
| 09982 | 黑旋风李逵      | xuanfeng@qq.com |        300.00 |
| 00835 | 菩提老祖        | NULL            |        119.50 |
| 00391 | 白素贞          | NULL            |        200.00 |
| 00031 | 许仙            | xuxian@qq.com   |        218.00 |
| 00054 | 不想毕业        | NULL            |        118.00 |
| 51234 | 好好说话        | say@qq.com      |        178.00 |
| 83223 | tellme          | NULL            |        172.00 |
+-------+-----------------+-----------------+---------------+

------------3,查询所有同学的成绩,及同学的个人信息

sql 复制代码
 select stu.sn,stu.name,stu.mail,sc.score from student stu,score sc where stu.student_id = sc.student_id;
+-------+-----------------+-----------------+-------+
| sn    | name            | mail            | score |
+-------+-----------------+-----------------+-------+
| 09982 | 黑旋风李逵      | xuanfeng@qq.com | 70.50 |
| 09982 | 黑旋风李逵      | xuanfeng@qq.com | 98.50 |
| 09982 | 黑旋风李逵      | xuanfeng@qq.com | 33.00 |
| 09982 | 黑旋风李逵      | xuanfeng@qq.com | 98.00 |
| 00835 | 菩提老祖        | NULL            | 60.00 |
| 00835 | 菩提老祖        | NULL            | 59.50 |
| 00391 | 白素贞          | NULL            | 33.00 |
| 00391 | 白素贞          | NULL            | 68.00 |
| 00391 | 白素贞          | NULL            | 99.00 |
| 00031 | 许仙            | xuxian@qq.com   | 67.00 |
| 00031 | 许仙            | xuxian@qq.com   | 23.00 |
| 00031 | 许仙            | xuxian@qq.com   | 56.00 |
| 00031 | 许仙            | xuxian@qq.com   | 72.00 |
| 00054 | 不想毕业        | NULL            | 81.00 |
| 00054 | 不想毕业        | NULL            | 37.00 |
| 51234 | 好好说话        | say@qq.com      | 56.00 |
| 51234 | 好好说话        | say@qq.com      | 43.00 |
| 51234 | 好好说话        | say@qq.com      | 79.00 |
| 83223 | tellme          | NULL            | 80.00 |
| 83223 | tellme          | NULL            | 92.00 |
+-------+-----------------+-----------------+-------+
sql 复制代码
 select stu.sn,stu.name,stu.mail,sc.score from student stu inner join score sc on stu.student_id = sc.student_id;
+-------+-----------------+-----------------+-------+
| sn    | name            | mail            | score |
+-------+-----------------+-----------------+-------+
| 09982 | 黑旋风李逵      | xuanfeng@qq.com | 70.50 |
| 09982 | 黑旋风李逵      | xuanfeng@qq.com | 98.50 |
| 09982 | 黑旋风李逵      | xuanfeng@qq.com | 33.00 |
| 09982 | 黑旋风李逵      | xuanfeng@qq.com | 98.00 |
| 00835 | 菩提老祖        | NULL            | 60.00 |
| 00835 | 菩提老祖        | NULL            | 59.50 |
| 00391 | 白素贞          | NULL            | 33.00 |
| 00391 | 白素贞          | NULL            | 68.00 |
| 00391 | 白素贞          | NULL            | 99.00 |
| 00031 | 许仙            | xuxian@qq.com   | 67.00 |
| 00031 | 许仙            | xuxian@qq.com   | 23.00 |
| 00031 | 许仙            | xuxian@qq.com   | 56.00 |
| 00031 | 许仙            | xuxian@qq.com   | 72.00 |
| 00054 | 不想毕业        | NULL            | 81.00 |
| 00054 | 不想毕业        | NULL            | 37.00 |
| 51234 | 好好说话        | say@qq.com      | 56.00 |
| 51234 | 好好说话        | say@qq.com      | 43.00 |
| 51234 | 好好说话        | say@qq.com      | 79.00 |
| 83223 | tellme          | NULL            | 80.00 |
| 83223 | tellme          | NULL            | 92.00 |
+-------+-----------------+-----------------+-------+

2,外连接

外连接分为左外连接和右外连接。如果联合查询,左侧的表完全显示我们就说是左外连接;右侧的表完 全显示我们就说是右外连接。

------------左外连接,表1完全显示

语法:

select 字段名 from 表名1 left join 表名2 on 连接条件

------------右外连接,表2完全显示

语法

select 字段名 from 表名1 right join 表名2 on 连接条件

------------1,显示,"老外学中文"同学的考试成绩 ,没有考试成绩也要显示

sql 复制代码
 select stu.sn,stu.name,stu.mail,sc.score from student stu left join score sc on stu.student_id = sc.student_id;
+-------+-----------------+------------------+-------+
| sn    | name            | mail             | score |
+-------+-----------------+------------------+-------+
| 09982 | 黑旋风李逵      | xuanfeng@qq.com  | 70.50 |
| 09982 | 黑旋风李逵      | xuanfeng@qq.com  | 98.50 |
| 09982 | 黑旋风李逵      | xuanfeng@qq.com  | 33.00 |
| 09982 | 黑旋风李逵      | xuanfeng@qq.com  | 98.00 |
| 00835 | 菩提老祖        | NULL             | 60.00 |
| 00835 | 菩提老祖        | NULL             | 59.50 |
| 00391 | 白素贞          | NULL             | 33.00 |
| 00391 | 白素贞          | NULL             | 68.00 |
| 00391 | 白素贞          | NULL             | 99.00 |
| 00031 | 许仙            | xuxian@qq.com    | 67.00 |
| 00031 | 许仙            | xuxian@qq.com    | 23.00 |
| 00031 | 许仙            | xuxian@qq.com    | 56.00 |
| 00031 | 许仙            | xuxian@qq.com    | 72.00 |
| 00054 | 不想毕业        | NULL             | 81.00 |
| 00054 | 不想毕业        | NULL             | 37.00 |
| 51234 | 好好说话        | say@qq.com       | 56.00 |
| 51234 | 好好说话        | say@qq.com       | 43.00 |
| 51234 | 好好说话        | say@qq.com       | 79.00 |
| 83223 | tellme          | NULL             | 80.00 |
| 83223 | tellme          | NULL             | 92.00 |
| 09527 | 老外学中文      | foreigner@qq.com |  NULL |
+-------+-----------------+------------------+-------+

------------2,学生表、成绩表、课程表3张表关联查询

sql 复制代码
 select stu.sn,stu.name,stu.mail,sc.score,co.name from student stu left join score sc on stu.student_id = sc.student_id left join course co on sc.course_id = co.course_id;
+-------+-----------------+------------------+-------+--------------------+
| sn    | name            | mail             | score | name               |
+-------+-----------------+------------------+-------+--------------------+
| 09982 | 黑旋风李逵      | xuanfeng@qq.com  | 70.50 | Java               |
| 09982 | 黑旋风李逵      | xuanfeng@qq.com  | 98.50 | 计算机原理         |
| 09982 | 黑旋风李逵      | xuanfeng@qq.com  | 33.00 | 高阶数学           |
| 09982 | 黑旋风李逵      | xuanfeng@qq.com  | 98.00 | 英文               |
| 00835 | 菩提老祖        | NULL             | 60.00 | Java               |
| 00835 | 菩提老祖        | NULL             | 59.50 | 高阶数学           |
| 00391 | 白素贞          | NULL             | 33.00 | Java               |
| 00391 | 白素贞          | NULL             | 68.00 | 计算机原理         |
| 00391 | 白素贞          | NULL             | 99.00 | 高阶数学           |
| 00031 | 许仙            | xuxian@qq.com    | 67.00 | Java               |
| 00031 | 许仙            | xuxian@qq.com    | 23.00 | 计算机原理         |
| 00031 | 许仙            | xuxian@qq.com    | 56.00 | 高阶数学           |
| 00031 | 许仙            | xuxian@qq.com    | 72.00 | 英文               |
| 00054 | 不想毕业        | NULL             | 81.00 | Java               |
| 00054 | 不想毕业        | NULL             | 37.00 | 高阶数学           |
| 51234 | 好好说话        | say@qq.com       | 56.00 | 中国传统文化       |
| 51234 | 好好说话        | say@qq.com       | 43.00 | 语文               |
| 51234 | 好好说话        | say@qq.com       | 79.00 | 英文               |
| 83223 | tellme          | NULL             | 80.00 | 中国传统文化       |
| 83223 | tellme          | NULL             | 92.00 | 英文               |
| 09527 | 老外学中文      | foreigner@qq.com |  NULL | NULL               |
+-------+-----------------+------------------+-------+--------------------+

3,自连接

自连接是在同一张表中进行查询,表要起两个不同的别名

------------1,显示所有"计算机原理"成绩比"Java"成绩高的成绩信息

这个我们来分析一下,计算机原理和java是课程表中,成绩是score表的内容,要取这两个表的笛卡尔积,java的course_id = 1,计算机原理的course_id = 3,这次我们不是比列而是行与行,

sql 复制代码
 select * from score sc1,score sc2 where sc1.course_id = 1 and sc2.course_id = 3 and sc2.score > sc1.score and sc1.student_id = sc2.student_id;
+----------+------------+-----------+-------+----------+------------+-----------+-------+
| score_id | student_id | course_id | score | score_id | student_id | course_id | score |
+----------+------------+-----------+-------+----------+------------+-----------+-------+
|        1 |          1 |         1 | 70.50 |        2 |          1 |         3 | 98.50 |
|        7 |          3 |         1 | 33.00 |        8 |          3 |         3 | 68.00 |
+----------+------------+-----------+-------+----------+------------+-----------+-------+

4,子查询

子查询就是嵌套查询,

------------1,查询与"不想毕业" 同学的同班同学:

sql 复制代码
select * from student where class_id = (select class_id from student where name = '不想毕业');
+------------+-------+-----------------+-----------------+----------+
| student_id | sn    | name            | mail            | class_id |
+------------+-------+-----------------+-----------------+----------+
|          1 | 09982 | 黑旋风李逵      | xuanfeng@qq.com |        1 |
|          2 | 00835 | 菩提老祖        | NULL            |        1 |
|          3 | 00391 | 白素贞          | NULL            |        1 |
|          4 | 00031 | 许仙            | xuxian@qq.com   |        1 |
|          5 | 00054 | 不想毕业        | NULL            |        1 |
+------------+-------+-----------------+-----------------+----------+

------------2,查询"语文"或"英文"课程的成绩信息

sql 复制代码
 select * from score where course_id in (select course_id from course where name = '语文' or name = '英文');
+----------+------------+-----------+-------+
| score_id | student_id | course_id | score |
+----------+------------+-----------+-------+
|       17 |          6 |         4 | 43.00 |
|        4 |          1 |         6 | 98.00 |
|       13 |          4 |         6 | 72.00 |
|       18 |          6 |         6 | 79.00 |
|       20 |          7 |         6 | 92.00 |
+----------+------------+-----------+-------+

exists 关键字

这个是如果子查询的语句有返回语句,整体查询语句就执行,反之不执行,

sql 复制代码
select * from score where not exists (select course_id from course where name = '语文' or name = '英文');
Empty set (0.00 sec)
sql 复制代码
 select * from score where exists (select course_id from course where name = '语文' or name = '英文');
+----------+------------+-----------+-------+
| score_id | student_id | course_id | score |
+----------+------------+-----------+-------+
|        1 |          1 |         1 | 70.50 |
|        2 |          1 |         3 | 98.50 |
|        3 |          1 |         5 | 33.00 |
|        4 |          1 |         6 | 98.00 |
|        5 |          2 |         1 | 60.00 |
|        6 |          2 |         5 | 59.50 |
|        7 |          3 |         1 | 33.00 |
|        8 |          3 |         3 | 68.00 |
|        9 |          3 |         5 | 99.00 |
|       10 |          4 |         1 | 67.00 |
|       11 |          4 |         3 | 23.00 |
|       12 |          4 |         5 | 56.00 |
|       13 |          4 |         6 | 72.00 |
|       14 |          5 |         1 | 81.00 |
|       15 |          5 |         5 | 37.00 |
|       16 |          6 |         2 | 56.00 |
|       17 |          6 |         4 | 43.00 |
|       18 |          6 |         6 | 79.00 |
|       19 |          7 |         2 | 80.00 |
|       20 |          7 |         6 | 92.00 |
+----------+------------+-----------+-------+

------------1,查询所有比"中文系2019级3班"平均分高的成绩信息:

sql 复制代码
select * from score sc where sc.score > (select avg(score) from score sc,class cl,student stu where cl.class_id = stu.class_id and sc.student_id = stu.student_id and cl.name = '中文系2019级3班');
+----------+------------+-----------+-------+
| score_id | student_id | course_id | score |
+----------+------------+-----------+-------+
|        1 |          1 |         1 | 70.50 |
|        2 |          1 |         3 | 98.50 |
|        4 |          1 |         6 | 98.00 |
|        9 |          3 |         5 | 99.00 |
|       13 |          4 |         6 | 72.00 |
|       14 |          5 |         1 | 81.00 |
|       18 |          6 |         6 | 79.00 |
|       19 |          7 |         2 | 80.00 |
|       20 |          7 |         6 | 92.00 |
+----------+------------+-----------+-------+

5,合并查询

去重union

不去重 union all

比如查询id<3,或者名字为英文的课程

sql 复制代码
select * from course where course_id<3 union select * from course where name = '英文';
+-----------+--------------------+
| course_id | name               |
+-----------+--------------------+
|         1 | Java               |
|         2 | 中国传统文化       |
|         6 | 英文               |
+-----------+--------------------+

union all可以去重,这里就不演示了。

相关推荐
LUCIAZZZ3 小时前
简单的SQL语句的快速复习
java·数据库·sql
Elastic 中国社区官方博客5 小时前
使用真实 Elasticsearch 进行高级集成测试
大数据·数据库·elasticsearch·搜索引擎·全文检索·jenkins·集成测试
@_@哆啦A梦5 小时前
Redis 基础命令
java·数据库·redis
fajianchen5 小时前
MySQL 索引存储结构
数据库·mysql
想做富婆6 小时前
oracle: 多表查询之联合查询[交集intersect, 并集union,差集minus]
数据库·oracle·联合查询
xianwu5437 小时前
反向代理模块jmh
开发语言·网络·数据库·c++·mysql
Leven1995277 小时前
Flink (十三) :Table API 与 DataStream API 的转换 (一)
数据库·sql·flink
geovindu8 小时前
neo4j-community-5.26.0 create new database
数据库·mysql·neo4j
MyY_DO8 小时前
maven mysql jdk nvm node npm 环境安装
java·mysql·maven
因特麦克斯9 小时前
索引的底层数据结构、B+树的结构、为什么InnoDB使用B+树而不是B树呢
数据库