当前位置:   article > 正文

MySQL表的查询进阶_mysql 名称等于张三,不等于就找李四

mysql 名称等于张三,不等于就找李四

目录

MySQL表的设计

查询进阶版本

插入查询结果-->属于新增

聚合查询

group by子句

having子句

联合查询

外连接

对比外连接和内连接:

自连接

子查询

合并查询


MySQL表的设计

我们一般将表的设计分为3种类型 一对一 , 一对多(或者是多对一),多对多.以下示例我以学生为例

  • 一对一

比如学生和账户 : 一个学生只能有一个账户(排除其他情况),一个账户只能包含一个学生.

这就是一种一对一的关系,我们如何设计表让其形成这样的关系呢??

学生和账户之间依靠 id来联系. 这就是一对一的关系.

我们可以 student(name accountId) account(accountId ,password)和student(name,studentId) account(studentId,password);  任意一种都可以,相关联的id可以使学生的学号也可以是账户的id;

设计表

  1. mysql> create table student(id int primary key auto_increment,name varchar(20));
  2. Query OK, 0 rows affected (0.03 sec)
  3. mysql> create table account(password int ,id int primary key auto_increment,foreign key(id) references student(id));
  4. Query OK, 0 rows affected (0.03 sec)
  • 一对多

什么情况会出现一对多呢?? 比如一个学生只能有一个班级,一个班级对应着多个学生.

学生和班级 也就是有两个表 学生表和班级表 两个依靠class_id(班级ID) 相关联 

 设计表

  1. mysql> create table class(class_id int primary key auto_increment,foreign key(class_id) references student(class_id));
  2. Query OK, 0 rows affected (0.03 sec)
  3. mysql> desc student;
  4. +----------+-------------+------+-----+---------+----------------+
  5. | Field | Type | Null | Key | Default | Extra |
  6. +----------+-------------+------+-----+---------+----------------+
  7. | class_id | int(11) | NO | PRI | NULL | auto_increment |
  8. | name | varchar(20) | YES | | NULL | |
  9. +----------+-------------+------+-----+---------+----------------+
  10. 2 rows in set (0.01 sec)
  11. create table class(name varchar(20), class_id int primary key auto_increment,foreign key(class_id) references student(class_id));
  12. Query OK, 0 rows affected (0.03 sec)
  13. mysql> desc class;
  14. +----------+-------------+------+-----+---------+----------------+
  15. | Field | Type | Null | Key | Default | Extra |
  16. +----------+-------------+------+-----+---------+----------------+
  17. | name | varchar(20) | YES | | NULL | |
  18. | class_id | int(11) | NO | PRI | NULL | auto_increment |
  19. +----------+-------------+------+-----+---------+----------------+
  20. 2 rows in set (0.01 sec)
  • 多对多

多对多的关系 比如 学生和课程之间的关系,一个学生可以有选择多门课程,一门课程可以包含多个学生. 多对多的关系我们需要借助学生和课程之间的一个表来联系,这个表保存着学生ID和课程ID

设计表

  1. mysql> create table student(student_id int primary key auto_increment,name varchar(20));
  2. Query OK, 0 rows affected (0.02 sec)
  3. mysql> create table course(course_id int primary key auto_increment,name varchar(20));
  4. Query OK, 0 rows affected (0.03 sec)
  5. mysql> create table student_course(student_id int,course_id int, foreign key(student_id) references student(student_id),foreign key(course_id) references course(course_id));
  6. Query OK, 0 rows affected (0.03 sec)
  7. mysql> desc student;
  8. +------------+-------------+------+-----+---------+----------------+
  9. | Field | Type | Null | Key | Default | Extra |
  10. +------------+-------------+------+-----+---------+----------------+
  11. | student_id | int(11) | NO | PRI | NULL | auto_increment |
  12. | name | varchar(20) | YES | | NULL | |
  13. +------------+-------------+------+-----+---------+----------------+
  14. 2 rows in set (0.01 sec)
  15. mysql> desc course;
  16. +-----------+-------------+------+-----+---------+----------------+
  17. | Field | Type | Null | Key | Default | Extra |
  18. +-----------+-------------+------+-----+---------+----------------+
  19. | course_id | int(11) | NO | PRI | NULL | auto_increment |
  20. | name | varchar(20) | YES | | NULL | |
  21. +-----------+-------------+------+-----+---------+----------------+
  22. 2 rows in set (0.01 sec)
  23. mysql> desc student_course;
  24. +------------+---------+------+-----+---------+-------+
  25. | Field | Type | Null | Key | Default | Extra |
  26. +------------+---------+------+-----+---------+-------+
  27. | student_id | int(11) | YES | MUL | NULL | |
  28. | course_id | int(11) | YES | MUL | NULL | |
  29. +------------+---------+------+-----+---------+-------+
  30. 2 rows in set (0.01 sec)

查询进阶版本

插入查询结果-->属于新增

插入查询就是将查询结果插入到一个临时表中,其中要注意的是,查询结果的临时表要与插入的表列数和类型一致.

  1. mysql> create table ID(name varchar(20),id int);
  2. Query OK, 0 rows affected (0.03 sec)
  3. mysql> insert into Id values('张三',90),('李四',23),('王五',45),('老李',11);
  4. Query OK, 4 rows affected (0.01 sec)
  5. mysql> insert into student(name,id) select * from ID;
  6. Query OK, 4 rows affected (0.01 sec)
  1. insert into student(name,id) select * from ID;
  2. 插入语法: insert into 表名(全列或者单列) select (全列或者单列) from 表名 [条件] ;

聚合查询

聚合函数

  • count

count->用来计算查询出数据的个数 ;

count(*) ->代表查询统计所有的数据,如果有NULL也计数,count(列)->代表统计这一列的数据个数,如果有NULL,不进行计数.

还要注意一点 如果count后面加上空格在加小括号 就会报错 SQL无法解析;

示例:

  1. mysql> select * from student;
  2. +----+---------+------+
  3. | id | chinese | math |
  4. +----+---------+------+
  5. | 1 | NULL | 58 |
  6. | 2 | 0 | NULL |
  7. | 3 | 56 | 89 |
  8. | 4 | 2 | 65 |
  9. +----+---------+------+
  10. 4 rows in set (0.00 sec)
  11. mysql> select count(*) from student;
  12. +----------+
  13. | count(*) |
  14. +----------+
  15. | 4 |
  16. +----------+
  17. 1 row in set (0.00 sec)
  18. -- 计算单列时:
  19. mysql> select count(chinese) from student;
  20. +----------------+
  21. | count(chinese) |
  22. +----------------+
  23. | 3 |
  24. +----------------+
  25. 1 row in set (0.00 sec)
  • sum

sum函数时进行求和,求和NULL不计入. NULL与任何数计算都是NULL,同时在进行聚合查询时也可以根据筛选条件进行查询

  1. select * from student;
  2. +----+---------+------+
  3. | id | chinese | math |
  4. +----+---------+------+
  5. | 1 | NULL | 58 |
  6. | 2 | 0 | NULL |
  7. | 3 | 56 | 89 |
  8. | 4 | 2 | 65 |
  9. +----+---------+------+
  10. mysql> select sum(chinese) from student;
  11. +--------------+
  12. | sum(chinese) |
  13. +--------------+
  14. | 58 |
  15. +--------------+
  16. -- 根据筛选math>60的总成绩
  17. select sum(math) from student where math>60;
  18. +-----------+
  19. | sum(math) |
  20. +-----------+
  21. | 154 |
  22. +-----------+
  • avg

avg用来计算平均数据

  1. select * from student;
  2. +----+---------+------+
  3. | id | chinese | math |
  4. +----+---------+------+
  5. | 1 | NULL | 58 |
  6. | 2 | 0 | NULL |
  7. | 3 | 56 | 89 |
  8. | 4 | 2 | 65 |
  9. +----+---------+------+
  10. select avg(math) from student;
  11. +-----------+
  12. | avg(math) |
  13. +-----------+
  14. | 70.6667 |
  15. +-----------+
  • max 和min

max和min 用来计算某一列的最大值和最小值

  1. select * from student;
  2. +----+---------+------+
  3. | id | chinese | math |
  4. +----+---------+------+
  5. | 1 | NULL | 58 |
  6. | 2 | 0 | NULL |
  7. | 3 | 56 | 89 |
  8. | 4 | 2 | 65 |
  9. +----+---------+------+
  10. 4 rows in set (0.00 sec)
  11. mysql> select max(math),min(math),max(chinese),min(chinese) from student;
  12. +-----------+-----------+--------------+--------------+
  13. | max(math) | min(math) | max(chinese) | min(chinese) |
  14. +-----------+-----------+--------------+--------------+
  15. | 89 | 58 | 56 | 0 |
  16. +-----------+-----------+--------------+--------------+

group by子句

group by 字句是依据列数来分组,列数相同的归为一组,查询时也可以使用聚合函数

语法 : select 要显示的列..可以使用聚合函数 from 表名 group by (列) <-根据这个列进行分组
  1. select * from student;
  2. +--------+--------+---------+------+---------+
  3. | name | gender | chinese | math | english |
  4. +--------+--------+---------+------+---------+
  5. | 张三 || 56 | 89 | 21 |
  6. | 李四 || 32 | 60 | 37 |
  7. | 王五 || 65 | 30 | 2 |
  8. | 小美 || 10 | 90 | 38 |
  9. +--------+--------+---------+------+---------+
  10. 4 rows in set (0.00 sec)
  11. select gender, avg(math) as "数学平均成绩" ,max(chinese) as "语文最高分",sum(english) from student group by gender;
  12. +--------+--------------------+-----------------+--------------+
  13. | gender | 数学平均成绩 | 语文最高分 | sum(english) |
  14. +--------+--------------------+-----------------+--------------+
  15. || 75.0000 | 32 | 75 |
  16. || 59.5000 | 65 | 23 |
  17. +--------+--------------------+-----------------+--------------+

having子句

having子句是 group的一个固定搭配,having相当于条件子句的where,但是在聚合查询之后,如果还要进行条件过滤,那我们就需要使用having子句与group by进行搭配使用;

-- 在进行条件筛选时有三种情况

  • 聚合之前选择
  1. mysql> -- 查询 除去张三同学 的性别的三科平均分数
  2. mysql> select gender,avg(math+chinese+english) from student where name!="张三" group by gender;
  3. +--------+---------------------------+
  4. | gender | avg(math+chinese+english) |
  5. +--------+---------------------------+
  6. || 133.5000 |
  7. || 155.0000 |
  8. +--------+---------------------------+
  • 聚合之后选择
  1. mysql> -- 查询 性别的平均成绩大于100的是男还是女
  2. mysql> select * from student;
  3. +--------+--------+---------+------+---------+
  4. | name | gender | chinese | math | english |
  5. +--------+--------+---------+------+---------+
  6. | 张三 || 56 | 89 | 21 |
  7. | 李四 || 32 | 60 | 37 |
  8. | 王五 || 65 | 30 | 2 |
  9. | 小美 || 10 | 90 | 38 |
  10. | 小明 || 85 | 96 | 32 |
  11. +--------+--------+---------+------+---------+
  12. mysql> select gender, avg(math+chinese+english) as "三科平均成绩" from student group by gender having avg(math+chinese+english)>=150.0;
  13. +--------+--------------------+
  14. | gender | 三科平均成绩 |
  15. +--------+--------------------+
  16. || 158.6667 |
  17. +--------+--------------------+
  • 聚合之前之后都查询
  1. mysql> select * from student;
  2. +--------+--------+---------+------+---------+
  3. | name | gender | chinese | math | english |
  4. +--------+--------+---------+------+---------+
  5. | 张三 || 56 | 89 | 21 |
  6. | 李四 || 32 | 60 | 37 |
  7. | 王五 || 65 | 30 | 2 |
  8. | 小美 || 10 | 90 | 38 |
  9. | 小明 || 85 | 96 | 32 |
  10. +--------+--------+---------+------+---------+
  11. mysql> select gender, avg(math+chinese+english) from student where name != "张三" group by gender having avg(math+chinese+english)>=140;
  12. +--------+---------------------------+
  13. | gender | avg(math+chinese+english) |
  14. +--------+---------------------------+
  15. || 155.0000 |
  16. +--------+---------------------------+
  • 总结

在聚合查询时 先整清楚是聚合之前还是聚合之后还是聚合之前聚合之后都要查询.

  • 如果是聚合之前查询先用where进行筛选在通过group by进行分组,可以使用聚合函数来显示最终结果
  • 如果是聚合之后查询,先要进行group by子句来分组,在使用having字句来过滤条件,可以使用聚合函数来显示最终结果
  • 如果聚合之前之后都要查询,先使用where把聚合之前的条件进行筛选,再根据group by来进行分组,在使用having子句在聚合之后进行查询,可以使用聚合函数来显示最终结果.

联合查询

联合查询就是将多表结合在一起查询,将两个表排列组合成一个表进行一系列操作,这也叫做笛卡尔积.

联合查询步骤:

  1. 先根据条件进行确定哪个表使用
  2. 在对多个表进行笛卡尔积
  3. 确定连接条件,过滤掉重复数据
  4. 进一步增加条件,查询与需要的结果相符
  5. 去掉无关的列,显示最终的结果

笛卡尔积: 

将两表进行合并 : select (要查询的列) from 表名 , 表名

还可以这样合并 : select(要查询的列) from 表名 join 表名 (可以join多个表名)..... on ....(条件)

笛卡尔积的列数就是几个表的列数之和

笛卡尔积的行数就是几个表的行数乘积

这也叫做内连接 -> 两个表中的列的交集 ->包含这两张表的数据

  1. drop table if exists classes;
  2. drop table if exists student;
  3. drop table if exists course;
  4. drop table if exists score;
  5. create table classes (id int primary key auto_increment, name varchar(20), `desc` varchar(100));
  6. create table student (id int primary key auto_increment, sn varchar(20), name varchar(20), qq_mail varchar(20) ,
  7. classes_id int);
  8. create table course(id int primary key auto_increment, name varchar(20));
  9. create table score(score decimal(3, 1), student_id int, course_id int);
  10. insert into classes(name, `desc`) values
  11. ('计算机系2019级1班', '学习了计算机原理、C和Java语言、数据结构和算法'),
  12. ('中文系2019级3班','学习了中国传统文学'),
  13. ('自动化2019级5班','学习了机械自动化');
  14. insert into student(sn, name, qq_mail, classes_id) values
  15. ('09982','黑旋风李逵','xuanfeng@qq.com',1),
  16. ('00835','菩提老祖',null,1),
  17. ('00391','白素贞',null,1),
  18. ('00031','许仙','xuxian@qq.com',1),
  19. ('00054','不想毕业',null,1),
  20. ('51234','好好说话','say@qq.com',2),
  21. ('83223','tellme',null,2),
  22. ('09527','老外学中文','foreigner@qq.com',2);
  23. insert into course(name) values
  24. ('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文');
  25. insert into score(score, student_id, course_id) values
  26. -- 黑旋风李逵
  27. (70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),
  28. -- 菩提老祖
  29. (60, 2, 1),(59.5, 2, 5),
  30. -- 白素贞
  31. (33, 3, 1),(68, 3, 3),(99, 3, 5),
  32. -- 许仙
  33. (67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6),
  34. -- 不想毕业
  35. (81, 5, 1),(37, 5, 5),
  36. -- 好好说话
  37. (56, 6, 2),(43, 6, 4),(79, 6, 6),
  38. -- tellme
  39. (80, 7, 2),(92, 7, 6);
  • 查询“许仙”同学的 成绩

1.先进行笛卡尔积

mysql> select * from student,score; -- 将两个表合并-进行笛卡尔积

2.既然雅查询许仙的乘积,那么它的学生id是一致的,不一致的就不符合条件

  1. mysql> select * from score,student where student.id = score.student_id;
  2. -- 分数表的学生id和学生表的学生id是相同的
  3. select student.name ,score.score from student join score on student.id = score.student_id and student.name = '许仙';
  4. -- 也可以使用join ... on

3.继续筛选条件 名字为许仙的.

mysql> select * from score,student where student.id = score.student_id and student.name="许仙";

4.精简表格

  1. mysql> select student.name ,score.score from student,score where student.id = score.student_id and student.name = '许仙';
  2. +--------+-------+
  3. | name | score |
  4. +--------+-------+
  5. | 许仙 | 67.0 |
  6. | 许仙 | 23.0 |
  7. | 许仙 | 56.0 |
  8. | 许仙 | 72.0 |
  9. +--------+-------+
  • 查询所有同学的总成绩,及同学的个人信息

首先,要查询同学的总成绩-->成绩表   同学的个人信息 ->同学表,我们将这两个表进行合并,要保证一个同学在成绩表和同学表一一对应,所以两个表的id要相等,因为要求同学的总成绩,我们就要使用聚合查询,首先先根据id进行分组,利用聚合函数sum求得每个id的总成绩.

  1. 保证每个学生唯一 ,进行学生表和分数表笛卡尔积
  1. -- 保证每个学生一一对应 学生表的id和分数表的id是相同的
  2. mysql> select * from student,score where student.id = score.student_id;

2.根据id进行分组

  1. mysql> select student.name,sum(score) from student,score where student.id = score.student_id group by id;
  2. +-----------------+------------+
  3. | name | sum(score) |
  4. +-----------------+------------+
  5. | 黑旋风李逵 | 300.0 |
  6. | 菩提老祖 | 119.5 |
  7. | 白素贞 | 200.0 |
  8. | 许仙 | 218.0 |
  9. | 不想毕业 | 118.0 |
  10. | 好好说话 | 178.0 |
  11. | tellme | 172.0 |
  12. +-----------------+------------+

3.使用聚合函数求得每个人的总成绩

  1. mysql> select student.name,student.id,student.qq_mail,student.classes_id,sum(score) as "总成绩" from student,score where student.id = score.student_id group by id;
  2. +-----------------+----+-----------------+------------+-----------+
  3. | name | id | qq_mail | classes_id | 总成绩 |
  4. +-----------------+----+-----------------+------------+-----------+
  5. | 黑旋风李逵 | 1 | xuanfeng@qq.com | 1 | 300.0 |
  6. | 菩提老祖 | 2 | NULL | 1 | 119.5 |
  7. | 白素贞 | 3 | NULL | 1 | 200.0 |
  8. | 许仙 | 4 | xuxian@qq.com | 1 | 218.0 |
  9. | 不想毕业 | 5 | NULL | 1 | 118.0 |
  10. | 好好说话 | 6 | say@qq.com | 2 | 178.0 |
  11. | tellme | 7 | NULL | 2 | 172.0 |
  12. +-----------------+----+-----------------+------------+-----------+
  • 查询所有同学的成绩,及同学的个人信息

这个题的意思是查询这个同学的所有课程成绩及信息.

那我们就需要准备同学->学生表,成绩->分数表,课程->课程表

将这三个表进行笛卡尔积

  1. select * from student join score join course ;
  2. -- 将这三个表进行笛卡尔积

可以知道一个学生在学生表的id和分数表的id就能确定某个学生的分数,学生表的分数的课程id和课程表的id就能确定这个学生选修的课程

  1. mysql> select student.id,student.name,course.name,score.score from student join score join course where student.id = score.student_id and course.id = score.course_id;
  2. +----+-----------------+--------------------+-------+
  3. | id | name | name | score |
  4. +----+-----------------+--------------------+-------+
  5. | 1 | 黑旋风李逵 | Java | 70.5 |
  6. | 1 | 黑旋风李逵 | 计算机原理 | 98.5 |
  7. | 1 | 黑旋风李逵 | 高阶数学 | 33.0 |
  8. | 1 | 黑旋风李逵 | 英文 | 98.0 |
  9. | 2 | 菩提老祖 | Java | 60.0 |
  10. | 2 | 菩提老祖 | 高阶数学 | 59.5 |
  11. | 3 | 白素贞 | Java | 33.0 |
  12. | 3 | 白素贞 | 计算机原理 | 68.0 |
  13. | 3 | 白素贞 | 高阶数学 | 99.0 |
  14. | 4 | 许仙 | Java | 67.0 |
  15. | 4 | 许仙 | 计算机原理 | 23.0 |
  16. | 4 | 许仙 | 高阶数学 | 56.0 |
  17. | 4 | 许仙 | 英文 | 72.0 |
  18. | 5 | 不想毕业 | Java | 81.0 |
  19. | 5 | 不想毕业 | 高阶数学 | 37.0 |
  20. | 6 | 好好说话 | 中国传统文化 | 56.0 |
  21. | 6 | 好好说话 | 语文 | 43.0 |
  22. | 6 | 好好说话 | 英文 | 79.0 |
  23. | 7 | tellme | 中国传统文化 | 80.0 |
  24. | 7 | tellme | 英文 | 92.0 |
  25. +----+-----------------+--------------------+-------+
  26. 20 rows in set (0.00 sec)

外连接

外连接与内连接相对应,内连接是将两个表的共有数据全部显示出来,而外连接是只显示一部分,即左半部分和右半部分.

  1. 语法:
  2. -- 左外连接 ->保证join左边的表完整,如果右侧不完整则为NULL
  3. select 列名 from 表名 left join 表名 on 条件
  4. -- 右外连接 ->保证join右边的表完整,如果左侧不完整则为NULL
  5. select 列名 from 表名 right join 表名 on 条件

创建的两张表:

  1. mysql> select * from score;
  2. +------+-------+
  3. | id | score |
  4. +------+-------+
  5. | 1 | 98 |
  6. | 2 | 76 |
  7. | 4 | 12 |
  8. +------+-------+
  9. 3 rows in set (0.02 sec)
  10. mysql> select * from student;
  11. +------+--------+
  12. | id | name |
  13. +------+--------+
  14. | 1 | 张三 |
  15. | 2 | 李四 |
  16. | 3 | 王五 |
  17. +------+--------+

左外连接:

  1. mysql> select name,score from score left join student on student.id = score.id;
  2. +--------+-------+
  3. | name | score |
  4. +--------+-------+
  5. | 张三 | 98 |
  6. | 李四 | 76 |
  7. | NULL | 12 |
  8. +--------+-------+
  9. 3 rows in set (0.00 sec)

右外连接:

  1. mysql> select name,score from score right join student on student.id = score.id;
  2. +--------+-------+
  3. | name | score |
  4. +--------+-------+
  5. | 张三 | 98 |
  6. | 李四 | 76 |
  7. | 王五 | NULL |
  8. +--------+-------+
  9. 3 rows in set (0.00 sec)

对比外连接和内连接:

 内连接只显式两张表共有的数据.

而外连接时都要显式,左外连接是保证左侧数据齐全准确,而右侧数据如果没有则显式NULL,右外连接是保证右侧数据齐全准确,而左侧数据如果没有则显式NULL

自连接

自连接,顾名思义就是自己连接自己,将两张一样的表进行笛卡尔积.

  • 显示所有“计算机原理”成绩比“Java”成绩高的成绩信息

 根据查询我们知道课程表中计算机原理是课程id 3号,而java是课程id1号,所以就转化为求课程id3号的同学大于课程id1号的同学; 

由于在分数表中课程id比较是要根据行和行进行比较,由于我们只能列和列之间进行比较,所以我们需要将两个一样的分数表进行笛卡尔积->也叫作自连接.

同样的保证学生不重复,要保证学生的信息一直,所以学生的id是相同的 ->这里要注意自连接时不能score join score ,自连接时必须要使用别名.

mysql> select * from score as s1 join score as s2 on s1.student_id = s2.student_id;

由于我们要比较3号课程和1号课程,所以我们要确保课程是3号和1号课程

  1. mysql> select * from score as s1 join score as s2 on s1.student_id = s2.student_id and s1.course_id = 3 and s2.course_id = 1;
  2. +-------+------------+-----------+-------+------------+-----------+
  3. | score | student_id | course_id | score | student_id | course_id |
  4. +-------+------------+-----------+-------+------------+-----------+
  5. | 98.5 | 1 | 3 | 70.5 | 1 | 1 |
  6. | 68.0 | 3 | 3 | 33.0 | 3 | 1 |
  7. | 23.0 | 4 | 3 | 67.0 | 4 | 1 |
  8. +-------+------------+-----------+-------+------------+-----------+

接下来在保证结果为3号课程的分数大于1号课程的分数

  1. mysql> select * from score as s1 join score as s2 on s1.student_id = s2.student_id and s1.course_id = 3 and s2.course_id = 1 and s1.score > s2.score;
  2. +-------+------------+-----------+-------+------------+-----------+
  3. | score | student_id | course_id | score | student_id | course_id |
  4. +-------+------------+-----------+-------+------------+-----------+
  5. | 98.5 | 1 | 3 | 70.5 | 1 | 1 |
  6. | 68.0 | 3 | 3 | 33.0 | 3 | 1 |
  7. +-------+------------+-----------+-------+------------+-----------+
  8. 2 rows in set (0.00 sec)
  • 自连接要注意的点:

在进行笛卡尔积的时候必须使用别名

子查询

这里的子查询就是套娃,也就是分步骤执行,将两个查询,通过查询某个重要的信息,再根据这个信息再次查询就得到最终结果.

子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询
 

  • 查询与“不想毕业” 同学的同班同学

第一步我们要先查询不想毕业同学的课程id

  1. mysql> select student.classes_id from student where name = "不想毕业";
  2. +------------+
  3. | classes_id |
  4. +------------+
  5. | 1 |
  6. +------------+

第二步查询classes_id和不想毕业同学一样的同学的名字,但是这里的名字不包括不想毕业,因为不想毕业的同班同学不能有它自己.

  1. mysql> select student.name from student where student.classes_id=1 and name!="不想毕业";
  2. +-----------------+
  3. | name |
  4. +-----------------+
  5. | 黑旋风李逵 |
  6. | 菩提老祖 |
  7. | 白素贞 |
  8. | 许仙 |
  9. +-----------------+

我们可以将上面两个步骤合并成一个如下:

  1. mysql> select name from student where student.classes_id = (select student.classes_id from student where student.name = "不想毕业") and student.name != "不想毕业";
  2. +-----------------+
  3. | name |
  4. +-----------------+
  5. | 黑旋风李逵 |
  6. | 菩提老祖 |
  7. | 白素贞 |
  8. | 许仙 |
  9. +-----------------+
  • 查询“语文”或“英文”课程的成绩信息

先根据语文和英文在对应的课程表中找到课程id

  1. mysql> select course.id from course where course.name = "语文" or course.name = "英文";
  2. +----+
  3. | id |
  4. +----+
  5. | 4 |
  6. | 6 |
  7. +----+

再根据课程id去分数表中找到对应的信息

  1. mysql> select * from score where score.course_id = 4 or score.course_id = 6;
  2. +-------+------------+-----------+
  3. | score | student_id | course_id |
  4. +-------+------------+-----------+
  5. | 98.0 | 1 | 6 |
  6. | 72.0 | 4 | 6 |
  7. | 43.0 | 6 | 4 |
  8. | 79.0 | 6 | 6 |
  9. | 92.0 | 7 | 6 |
  10. +-------+------------+-----------+
  11. -- 这里也可以使用 in
  12. mysql> select * from score where score.course_id in(4,6);
  13. +-------+------------+-----------+
  14. | score | student_id | course_id |
  15. +-------+------------+-----------+
  16. | 98.0 | 1 | 6 |
  17. | 72.0 | 4 | 6 |
  18. | 43.0 | 6 | 4 |
  19. | 79.0 | 6 | 6 |
  20. | 92.0 | 7 | 6 |
  21. +-------+------------+-----------+

将这两个步骤进行合并操作

  1. select * from score where score.course_id in(select course.id from course where course.name in ("英文","语文"));
  2. +-------+------------+-----------+
  3. | score | student_id | course_id |
  4. +-------+------------+-----------+
  5. | 98.0 | 1 | 6 |
  6. | 72.0 | 4 | 6 |
  7. | 43.0 | 6 | 4 |
  8. | 79.0 | 6 | 6 |
  9. | 92.0 | 7 | 6 |
  10. +-------+------------+-----------+

合并查询

就是将两个查询合并成一个

比如我要查询id小于3,或者名字为“英文”的课程

  1. mysql> select * from course where course.id<3 or course.name = "英文";
  2. +----+--------------------+
  3. | id | name |
  4. +----+--------------------+
  5. | 1 | Java |
  6. | 2 | 中国传统文化 |
  7. | 6 | 英文 |
  8. +----+--------------------+

我们可以查询id<3的,在查询name = 英文的,然后将两个查询进行合并

  1. mysql> select * from course where course.id < 3 union select * from course where course.name = "英文";
  2. +----+--------------------+
  3. | id | name |
  4. +----+--------------------+
  5. | 1 | Java |
  6. | 2 | 中国传统文化 |
  7. | 6 | 英文 |
  8. +----+--------------------+
  9. 3 rows in set (0.00 sec)
  • union 该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行
     
  • union all 该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行
     
  1. mysql> select id from course where course.name = "英文" union all select id from course where course.name = "英文";
  2. +----+
  3. | id |
  4. +----+
  5. | 6 |
  6. | 6 |
  7. +----+
  8. 2 rows in set (0.00 sec)
  9. mysql> select id from course where course.name = "英文" union select id from course where course.name = "英文";
  10. +----+
  11. | id |
  12. +----+
  13. | 6 |
  14. +----+
  15. 1 row in set (0.00 sec)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/490601
推荐阅读
相关标签
  

闽ICP备14008679号