mysql数据库学习之数据查询进阶操作(三)
文章目录
- 一、连接查询
- 1.1 数据准备
- 1.2 内连接:inner join
- 1.3 左连接: left join
- 1.4 右连接: right join
- 二、自关联
- 2.1 数据准备
- 2.2 自连接
- 三、子查询
- 四、查询演练
- 4.1 数据准备
- 4.2 案例练习
一、连接查询
1.1 数据准备
-- 创建students表
drop table if exists students;
create table students (
studentNo varchar(10) primary key,
name varchar(10),
sex varchar(1),
hometown varchar(20),
age tinyint(4),
class varchar(10),
card varchar(20)
);-- 插入学生数据
insert into students values
('001', '王昭君', '女', '北京', 20, '1班', '340322199001247654'),
('002', '诸葛亮', '男', '上海', 18, '2班', '340322199002242354'),
('003', '张飞', '男', '南京', 24, '3班', '340322199003247654'),
('004', '白起', '男', '安徽', 22, '4班', '340322199005247654'),
('005', '大乔', '女', '天津', 19, '3班', '340322199004247654'),
('006', '孙尚香', '女', '河北', 18, '1班', '340322199006247654'),
('007', '百里玄策', '男', '山西', 20, '2班', '340322199007247654'),
('008', '小乔', '女', '河南', 15, '3班', null),
('009', '百里守约', '男', '湖南', 21, '1班', ''),
('010', '妲己', '女', '广东', 26, '2班', '340322199607247654'),
('011', '李白', '男', '北京', 30, '4班', '340322199005267754'),
('012', '孙膑', '男', '新疆', 26, '3班', '340322199000297655');-- 运行结果
+-----------+--------------+------+----------+------+-------+--------------------+
| studentNo | name | sex | hometown | age | class | card |
+-----------+--------------+------+----------+------+-------+--------------------+
| 001 | 王昭君 | 女 | 北京 | 20 | 1班 | 340322199001247654 |
| 002 | 诸葛亮 | 男 | 上海 | 18 | 2班 | 340322199002242354 |
| 003 | 张飞 | 男 | 南京 | 24 | 3班 | 340322199003247654 |
| 004 | 白起 | 男 | 安徽 | 22 | 4班 | 340322199005247654 |
| 005 | 大乔 | 女 | 天津 | 19 | 3班 | 340322199004247654 |
| 006 | 孙尚香 | 女 | 河北 | 18 | 1班 | 340322199006247654 |
| 007 | 百里玄策 | 男 | 山西 | 20 | 2班 | 340322199007247654 |
| 008 | 小乔 | 女 | 河南 | 15 | 3班 | NULL |
| 009 | 百里守约 | 男 | 湖南 | 21 | 1班 | |
| 010 | 妲己 | 女 | 广东 | 26 | 2班 | 340322199607247654 |
| 011 | 李白 | 男 | 北京 | 30 | 4班 | 340322199005267754 |
| 012 | 孙膑 | 男 | 新疆 | 26 | 3班 | 340322199000297655 |
+-----------+--------------+------+----------+------+-------+--------------------+-- 创建课程表( courses)
drop table if exists courses;
create table courses (
courseNo int(10) unsigned primary key auto_increment,
name varchar(10)
);-- 插入课程信息
insert into courses values (null, 'mysql数据库'), (null, 'python自动化测试'), (null, 'linux系统学习'),(null, 'web系统测试'), (null, '单元测试'), (null, '测试流程一体化');
-- 运行结果
+----------+--------------+
| courseNo | name |
+----------+--------------+
| 1 | 数据库 |
| 2 | qtp |
| 3 | linux |
| 4 | 系统测试 |
| 5 | 单元测试 |
| 6 | 测试过程 |
+----------+--------------+-- 创建分数表
drop table if exists scores;
create table scores (
id int(10) unsigned primary key auto_increment,
courseNo int(10),
studentno varchar(10),
score tinyint(4)
);-- 插入课程分数信息
insert into scores values (0, 1, '001', 90), (0, 1, '002', 75),
(0, 2, '002', 98),(0, 3, '001', 86),(0, 3, '003', 80),
(0, 4, '004', 79),(0, 5, '005', 96),(0, 6, '006', 80);
-- 运行结果
+----+----------+-----------+-------+
| id | courseNo | studentno | score |
+----+----------+-----------+-------+
| 1 | 1 | 001 | 90 |
| 2 | 1 | 002 | 75 |
| 3 | 2 | 002 | 98 |
| 4 | 3 | 001 | 86 |
| 5 | 3 | 003 | 80 |
| 6 | 4 | 004 | 79 |
| 7 | 5 | 005 | 96 |
| 8 | 6 | 006 | 80 |
+----+----------+-----------+-------+
1.2 内连接:inner join
-
定义:连接两个表时,取的是两个表中都存在的数据。(取交集)
-
语法格式
select * from 表1 inner join 表2 on 表1.列=表2.列 同等于 select * from 表1,表2 where 表1.列=表2.列
-
示例
-
例1:查询学生信息及学生的成绩
-- 两行命令都可以实现 -- select * from students as stu, scores as sc where stu.studentNo = sc.studentNo; -- select * from students inner join scores on students.studentNo = scores.studentNo;mysql> select * from students inner join scores on students.studentNo = scores.studentNo; +-----------+-----------+------+----------+------+-------+--------------------+----+----------+-----------+-------+ | studentNo | name | sex | hometown | age | class | card | id | courseNo | studentno | score | +-----------+-----------+------+----------+------+-------+--------------------+----+----------+-----------+-------+ | 001 | 王昭君 | 女 | 北京 | 20 | 1班 | 340322199001247654 | 1 | 1 | 001 | 90 | | 002 | 诸葛亮 | 男 | 上海 | 18 | 2班 | 340322199002242354 | 2 | 1 | 002 | 75 | | 002 | 诸葛亮 | 男 | 上海 | 18 | 2班 | 340322199002242354 | 3 | 2 | 002 | 98 | | 001 | 王昭君 | 女 | 北京 | 20 | 1班 | 340322199001247654 | 4 | 3 | 001 | 86 | | 003 | 张飞 | 男 | 南京 | 24 | 3班 | 340322199003247654 | 5 | 3 | 003 | 80 | | 004 | 白起 | 男 | 安徽 | 22 | 4班 | 340322199005247654 | 6 | 4 | 004 | 79 | | 005 | 大乔 | 女 | 天津 | 19 | 3班 | 340322199004247654 | 7 | 5 | 005 | 96 | | 006 | 孙尚香 | 女 | 河北 | 18 | 1班 | 340322199006247654 | 8 | 6 | 006 | 80 | +-----------+-----------+------+----------+------+-------+--------------------+----+----------+-----------+-------+ 8 rows in set (0.00 sec)
-
例2:查询课程信息及课程的成绩
mysql> select * from courses cs inner join scores sc on cs.courseNo = sc.courseNo; +----------+--------------+----+----------+-----------+-------+ | courseNo | name | id | courseNo | studentno | score | +----------+--------------+----+----------+-----------+-------+ | 1 | 数据库 | 1 | 1 | 001 | 90 | | 1 | 数据库 | 2 | 1 | 002 | 75 | | 2 | qtp | 3 | 2 | 002 | 98 | | 3 | linux | 4 | 3 | 001 | 86 | | 3 | linux | 5 | 3 | 003 | 80 | | 4 | 系统测试 | 6 | 4 | 004 | 79 | | 5 | 单元测试 | 7 | 5 | 005 | 96 | | 6 | 测试过程 | 8 | 6 | 006 | 80 | +----------+--------------+----+----------+-----------+-------+ 8 rows in set (0.00 sec)
-
例3:查询王昭君的成绩,要求显示姓名、课程号、成绩
mysql> select stu.name, sc.courseNo, sc.score from students stu inner join scores sc on stu.studentNo = sc.studentNo where stu.name = '王昭君'; +-----------+----------+-------+ | name | courseNo | score | +-----------+----------+-------+ | 王昭君 | 1 | 90 | | 王昭君 | 3 | 86 | +-----------+----------+-------+ 2 rows in set (0.01 sec)
-
1.3 左连接: left join
-
定义:连接两个表时,取的是左表中特有的数据,对于右表中不存在的数据,用null来填充。
-
语法格式
- select * from 表1 left join 表2 on 表1.列=表2.列
-
示例
-
查询所有学生的成绩,包括没有成绩的学生
mysql> select * from students stu left join scores sc on stu.studentNo = sc.studentNo; +-----------+--------------+------+----------+------+-------+--------------------+------+----------+-----------+-------+ | studentNo | name | sex | hometown | age | class | card | id | courseNo | studentno | score | +-----------+--------------+------+----------+------+-------+--------------------+------+----------+-----------+-------+ | 001 | 王昭君 | 女 | 北京 | 20 | 1班 | 340322199001247654 | 4 | 3 | 001 | 86 | | 001 | 王昭君 | 女 | 北京 | 20 | 1班 | 340322199001247654 | 1 | 1 | 001 | 90 | | 002 | 诸葛亮 | 男 | 上海 | 18 | 2班 | 340322199002242354 | 3 | 2 | 002 | 98 | | 002 | 诸葛亮 | 男 | 上海 | 18 | 2班 | 340322199002242354 | 2 | 1 | 002 | 75 | | 003 | 张飞 | 男 | 南京 | 24 | 3班 | 340322199003247654 | 5 | 3 | 003 | 80 | | 004 | 白起 | 男 | 安徽 | 22 | 4班 | 340322199005247654 | 6 | 4 | 004 | 79 | | 005 | 大乔 | 女 | 天津 | 19 | 3班 | 340322199004247654 | 7 | 5 | 005 | 96 | | 006 | 孙尚香 | 女 | 河北 | 18 | 1班 | 340322199006247654 | 8 | 6 | 006 | 80 | | 007 | 百里玄策 | 男 | 山西 | 20 | 2班 | 340322199007247654 | NULL | NULL | NULL | NULL | | 008 | 小乔 | 女 | 河南 | 15 | 3班 | NULL | NULL | NULL | NULL | NULL | | 009 | 百里守约 | 男 | 湖南 | 21 | 1班 | | NULL | NULL | NULL | NULL | | 010 | 妲己 | 女 | 广东 | 26 | 2班 | 340322199607247654 | NULL | NULL | NULL | NULL | | 011 | 李白 | 男 | 北京 | 30 | 4班 | 340322199005267754 | NULL | NULL | NULL | NULL | | 012 | 孙膑 | 男 | 新疆 | 26 | 3班 | 340322199000297655 | NULL | NULL | NULL | NULL | +-----------+--------------+------+----------+------+-------+--------------------+------+----------+-----------+-------+ 14 rows in set (0.00 sec)
-
查询所有学生的成绩,包括没有成绩的学生,需要显示课程名
mysql> select * from students left join scores on students.studentNo = scores.studentNo left join courses on scores.courseNo = courses.courseNo;+-----------+--------------+------+----------+------+-------+--------------------+------+----------+-----------+-------+----------+--------------+ | studentNo | name | sex | hometown | age | class | card | id | courseNo | studentno | score | courseNo | name | +-----------+--------------+------+----------+------+-------+--------------------+------+----------+-----------+-------+----------+--------------+ | 001 | 王昭君 | 女 | 北京 | 20 | 1班 | 340322199001247654 | 4 | 3 | 001 | 86 | 3 | linux | | 001 | 王昭君 | 女 | 北京 | 20 | 1班 | 340322199001247654 | 1 | 1 | 001 | 90 | 1 | 数据库 | | 002 | 诸葛亮 | 男 | 上海 | 18 | 2班 | 340322199002242354 | 3 | 2 | 002 | 98 | 2 | qtp | | 002 | 诸葛亮 | 男 | 上海 | 18 | 2班 | 340322199002242354 | 2 | 1 | 002 | 75 | 1 | 数据库 | | 003 | 张飞 | 男 | 南京 | 24 | 3班 | 340322199003247654 | 5 | 3 | 003 | 80 | 3 | linux | | 004 | 白起 | 男 | 安徽 | 22 | 4班 | 340322199005247654 | 6 | 4 | 004 | 79 | 4 | 系统测试 | | 005 | 大乔 | 女 | 天津 | 19 | 3班 | 340322199004247654 | 7 | 5 | 005 | 96 | 5 | 单元测试 | | 006 | 孙尚香 | 女 | 河北 | 18 | 1班 | 340322199006247654 | 8 | 6 | 006 | 80 | 6 | 测试过程 | | 007 | 百里玄策 | 男 | 山西 | 20 | 2班 | 340322199007247654 | NULL | NULL | NULL | NULL | NULL | NULL | | 008 | 小乔 | 女 | 河南 | 15 | 3班 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | | 009 | 百里守约 | 男 | 湖南 | 21 | 1班 | | NULL | NULL | NULL | NULL | NULL | NULL | | 010 | 妲己 | 女 | 广东 | 26 | 2班 | 340322199607247654 | NULL | NULL | NULL | NULL | NULL | NULL | | 011 | 李白 | 男 | 北京 | 30 | 4班 | 340322199005267754 | NULL | NULL | NULL | NULL | NULL | NULL | | 012 | 孙膑 | 男 | 新疆 | 26 | 3班 | 340322199000297655 | NULL | NULL | NULL | NULL | NULL | NULL | +-----------+--------------+------+----------+------+-------+--------------------+------+----------+-----------+-------+----------+--------------+ 14 rows in set (0.00 sec)
-
1.4 右连接: right join
-
定义:连接两个表时,取的是右表中特有的数据,对于左表中不存在的数据,用null来填充。
-
语法格式
- select * from 表1 right join 表2 on 表1.列=表2.列
-
案例
-
例1:查询所有学生的成绩,包括没有成绩的学生
mysql> select * from scores right join students on scores.studentNo = students.studentNo; +------+----------+-----------+-------+-----------+--------------+------+----------+------+-------+--------------------+ | id | courseNo | studentno | score | studentNo | name | sex | hometown | age | class | card | +------+----------+-----------+-------+-----------+--------------+------+----------+------+-------+--------------------+ | 4 | 3 | 001 | 86 | 001 | 王昭君 | 女 | 北京 | 20 | 1班 | 340322199001247654 | | 1 | 1 | 001 | 90 | 001 | 王昭君 | 女 | 北京 | 20 | 1班 | 340322199001247654 | | 3 | 2 | 002 | 98 | 002 | 诸葛亮 | 男 | 上海 | 18 | 2班 | 340322199002242354 | | 2 | 1 | 002 | 75 | 002 | 诸葛亮 | 男 | 上海 | 18 | 2班 | 340322199002242354 | | 5 | 3 | 003 | 80 | 003 | 张飞 | 男 | 南京 | 24 | 3班 | 340322199003247654 | | 6 | 4 | 004 | 79 | 004 | 白起 | 男 | 安徽 | 22 | 4班 | 340322199005247654 | | 7 | 5 | 005 | 96 | 005 | 大乔 | 女 | 天津 | 19 | 3班 | 340322199004247654 | | 8 | 6 | 006 | 80 | 006 | 孙尚香 | 女 | 河北 | 18 | 1班 | 340322199006247654 | | NULL | NULL | NULL | NULL | 007 | 百里玄策 | 男 | 山西 | 20 | 2班 | 340322199007247654 | | NULL | NULL | NULL | NULL | 008 | 小乔 | 女 | 河南 | 15 | 3班 | NULL | | NULL | NULL | NULL | NULL | 009 | 百里守约 | 男 | 湖南 | 21 | 1班 | | | NULL | NULL | NULL | NULL | 010 | 妲己 | 女 | 广东 | 26 | 2班 | 340322199607247654 | | NULL | NULL | NULL | NULL | 011 | 李白 | 男 | 北京 | 30 | 4班 | 340322199005267754 | | NULL | NULL | NULL | NULL | 012 | 孙膑 | 男 | 新疆 | 26 | 3班 | 340322199000297655 | +------+----------+-----------+-------+-----------+--------------+------+----------+------+-------+--------------------+ 14 rows in set (0.00 sec)
-
例2:查询所有学生的成绩,包括没有成绩的学生,需要显示课程名
students.studentNo = scores.studentNo; +------+----------+-----------+-------+----------+--------------+-----------+--------------+------+----------+------+-------+--------------------+ | id | courseNo | studentno | score | courseNo | name | studentNo | name | sex | hometown | age | class | card | +------+----------+-----------+-------+----------+--------------+-----------+--------------+------+----------+------+-------+--------------------+ | 1 | 1 | 001 | 90 | 1 | 数据库 | 001 | 王昭君 | 女 | 北京 | 20 | 1班 | 340322199001247654 | | 4 | 3 | 001 | 86 | 3 | linux | 001 | 王昭君 | 女 | 北京 | 20 | 1班 | 340322199001247654 | | 2 | 1 | 002 | 75 | 1 | 数据库 | 002 | 诸葛亮 | 男 | 上海 | 18 | 2班 | 340322199002242354 | | 3 | 2 | 002 | 98 | 2 | qtp | 002 | 诸葛亮 | 男 | 上海 | 18 | 2班 | 340322199002242354 | | 5 | 3 | 003 | 80 | 3 | linux | 003 | 张飞 | 男 | 南京 | 24 | 3班 | 340322199003247654 | | 6 | 4 | 004 | 79 | 4 | 系统测试 | 004 | 白起 | 男 | 安徽 | 22 | 4班 | 340322199005247654 | | 7 | 5 | 005 | 96 | 5 | 单元测试 | 005 | 大乔 | 女 | 天津 | 19 | 3班 | 340322199004247654 | | 8 | 6 | 006 | 80 | 6 | 测试过程 | 006 | 孙尚香 | 女 | 河北 | 18 | 1班 | 340322199006247654 | | NULL | NULL | NULL | NULL | NULL | NULL | 007 | 百里玄策 | 男 | 山西 | 20 | 2班 | 340322199007247654 | | NULL | NULL | NULL | NULL | NULL | NULL | 008 | 小乔 | 女 | 河南 | 15 | 3班 | NULL | | NULL | NULL | NULL | NULL | NULL | NULL | 009 | 百里守约 | 男 | 湖南 | 21 | 1班 | | | NULL | NULL | NULL | NULL | NULL | NULL | 010 | 妲己 | 女 | 广东 | 26 | 2班 | 340322199607247654 | | NULL | NULL | NULL | NULL | NULL | NULL | 011 | 李白 | 男 | 北京 | 30 | 4班 | 340322199005267754 | | NULL | NULL | NULL | NULL | NULL | NULL | 012 | 孙膑 | 男 | 新疆 | 26 | 3班 | 340322199000297655 | +------+----------+-----------+-------+----------+--------------+-----------+--------------+------+----------+------+-------+--------------------+ 14 rows in set (0.00 sec)
-
二、自关联
2.1 数据准备
drop table if exists areas;
create table areas(aid varchar(10) primary key, atitle varchar(20),pid varchar(10));-- 运行结果
+--------+--------------+--------+
| aid | atitle | pid |
+--------+--------------+--------+
| 130000 | 河北省 | NULL |
| 130100 | 石家庄市 | 130000 |
| 130400 | 邯郸市 | 130000 |
| 130600 | 保定市 | 130000 |
| 130700 | 张家口市 | 130000 |
| 130800 | 承德市 | 130000 |
| 410000 | 河南省 | NULL |
| 410100 | 郑州市 | 410000 |
| 410101 | 中原区 | 410100 |
| 410102 | 二七区 | 410100 |
| 410300 | 洛阳市 | 410000 |
| 410301 | 洛龙区 | 410300 |
| 410500 | 安阳市 | 410000 |
| 410700 | 新乡市 | 410000 |
| 410800 | 焦作市 | 410000 |
+--------+--------------+--------+
2.2 自连接
-
应用场景
- 在同一张表中,用两个字段来表示记录之间的层级关系时,可以使用自关联。比如地址信息中的省、市的信息
- 省、市、区的信息,一般不会分开放在不同的表里面进行存储,而是放在同一个表当中。
-
说明:要通过自关联进行查询时,当前自关联的表当中一定会存在两个相关联的字段,
自关联要用别名
-
语法格式
select * from 表名 as 别名1 inner join 表名 as 别名2 on 别名1.列=别名2.列
-
查询实现
-
inner join 关联同一个表,不同的字段
-
自关联要用别名
-
-
示例
-
例1:查询河南省所有的市
mysql> select * from areas as a1 inner join areas as a2 on a1.aid=a2.pid where a1.atitle='河南省'; +--------+-----------+------+--------+-----------+--------+ | aid | atitle | pid | aid | atitle | pid | +--------+-----------+------+--------+-----------+--------+ | 410000 | 河南省 | NULL | 410100 | 郑州市 | 410000 | | 410000 | 河南省 | NULL | 410300 | 洛阳市 | 410000 | | 410000 | 河南省 | NULL | 410500 | 安阳市 | 410000 | | 410000 | 河南省 | NULL | 410700 | 新乡市 | 410000 | | 410000 | 河南省 | NULL | 410800 | 焦作市 | 410000 | +--------+-----------+------+--------+-----------+--------+ 5 rows in set (0.00 sec)
-
例2:查询郑州市的所有的区
mysql> select * from areas as a1 inner join areas as a2 on a1.aid=a2.pid where a1.atitle='郑州市'; +--------+-----------+--------+--------+-----------+--------+ | aid | atitle | pid | aid | atitle | pid | +--------+-----------+--------+--------+-----------+--------+ | 410100 | 郑州市 | 410000 | 410101 | 中原区 | 410100 | | 410100 | 郑州市 | 410000 | 410102 | 二七区 | 410100 | +--------+-----------+--------+--------+-----------+--------+ 2 rows in set (0.00 sec)
-
例3:查询河南省的所有的市区
mysql> select * from areas as a1 inner join areas as a2 on a1.aid=a2.pid left join areas as a3 on a2.aid=a3.pid where a1.atitle='河南省'; +--------+-----------+------+--------+-----------+--------+--------+-----------+--------+ | aid | atitle | pid | aid | atitle | pid | aid | atitle | pid | +--------+-----------+------+--------+-----------+--------+--------+-----------+--------+ | 410000 | 河南省 | NULL | 410100 | 郑州市 | 410000 | 410102 | 二七区 | 410100 | | 410000 | 河南省 | NULL | 410100 | 郑州市 | 410000 | 410101 | 中原区 | 410100 | | 410000 | 河南省 | NULL | 410300 | 洛阳市 | 410000 | 410301 | 洛龙区 | 410300 | | 410000 | 河南省 | NULL | 410500 | 安阳市 | 410000 | NULL | NULL | NULL | | 410000 | 河南省 | NULL | 410700 | 新乡市 | 410000 | NULL | NULL | NULL | | 410000 | 河南省 | NULL | 410800 | 焦作市 | 410000 | NULL | NULL | NULL | +--------+-----------+------+--------+-----------+--------+--------+-----------+--------+ 6 rows in set (0.01 sec)
-
三、子查询
-
简介:将一条SQL查询的语句嵌入在其他的SQL语句中,被嵌入的SQL语句称之为子查询,其他的SQL称之为主查询
-
子查询辅助主查询,要么充当条件,要么充当数据源。
-
子查询是一条完整的、可单独执行的select查询语句
-
-
充当条件示例(
数据源于连接查询
)-
例1:查询王昭君的成绩,要求显示成绩(标量子查询)
mysql> select * from scores where studentNo=(select studentNo from students where name='王昭君'); +----+----------+-----------+-------+ | id | courseNo | studentno | score | +----+----------+-----------+-------+ | 1 | 1 | 001 | 90 | | 4 | 3 | 001 | 86 | +----+----------+-----------+-------+ 2 rows in set (0.01 sec)
-
例2:查询18岁的学生的成绩,要求显示成绩(列子查询)
mysql> select score from scores where studentNo in (select studentNo from students where age=18); +-------+ | score | +-------+ | 75 | | 98 | | 80 | +-------+ 3 rows in set (0.00 sec)
-
例3:查询和王昭君同班、同龄的学生信息(行子查询)
mysql> select * from students where (class, age)=(select class, age from students where name='王昭君'); +-----------+-----------+------+----------+------+-------+--------------------+ | studentNo | name | sex | hometown | age | class | card | +-----------+-----------+------+----------+------+-------+--------------------+ | 001 | 王昭君 | 女 | 北京 | 20 | 1班 | 340322199001247654 | +-----------+-----------+------+----------+------+-------+--------------------+ 1 row in set (0.00 sec)
-
-
充当数据源示例(
数据源于连接查询
)-
例1:查询数据库和系统测试的课程成绩
mysql> select * from scores as sc inner join (select * from courses where name in ('数据库','系统测试')) as co on sc.courseNo=co.courseNo; +----+----------+-----------+-------+----------+--------------+ | id | courseNo | studentno | score | courseNo | name | +----+----------+-----------+-------+----------+--------------+ | 1 | 1 | 001 | 90 | 1 | 数据库 | | 2 | 1 | 002 | 75 | 1 | 数据库 | | 6 | 4 | 004 | 79 | 4 | 系统测试 | +----+----------+-----------+-------+----------+--------------+ 3 rows in set (0.00 sec)
-
-
充当特定关键字示例(
数据源于连接查询
)-
in 范围
-
语法格式:
- 主查询 where 条件 in (列子查询)
-
示例
-
例1:查询大于平均年龄的学生
mysql> select name,age from students where age > (select avg(age) from students); +--------+------+ | name | age | +--------+------+ | 张飞 | 24 | | 白起 | 22 | | 妲己 | 26 | | 李白 | 30 | | 孙膑 | 26 | +--------+------+ 5 rows in set (0.00 sec)
-
例2:查询年龄在18-20之间的学生的成绩。
mysql> select * from scores where studentno in (select studentno from students where age in (18,20)); +----+----------+-----------+-------+ | id | courseNo | studentno | score | +----+----------+-----------+-------+ | 1 | 1 | 001 | 90 | | 2 | 1 | 002 | 75 | | 3 | 2 | 002 | 98 | | 4 | 3 | 001 | 86 | | 8 | 6 | 006 | 80 | +----+----------+-----------+-------+ 5 rows in set (0.00 sec):
-
-
-
any | some 任意
- 语法格式: 主查询 where 列 = all(列子查询)
-
all 所有
- 语法格式: 主查询 where 列 = any (列子查询)
-
四、查询演练
4.1 数据准备
-- 创建部门表
drop table if exists departments;
create table departments (
deptid int(10) primary key,
deptname varchar(20) not null -- 部门名称
);
-- 插入数据
insert into departments values ('1001', '市场部');
insert into departments values ('1002', '测试部');
insert into departments values ('1003', '开发部');-- 运行结果
+--------+-----------+
| deptid | deptname |
+--------+-----------+
| 1001 | 市场部 |
| 1002 | 测试部 |
| 1003 | 开发部 |
+--------+-----------+-- 创建员工表
drop table if exists employees;
create table employees (
empid int(10) primary key,
empname varchar(20) not null, -- 姓名
sex varchar(4) default null, -- 性别
deptid int(20) default null, -- 部门编号
jobs varchar(20) default null, -- 岗位
politicalstatus varchar(20) default null, -- 政治面貌
leader int(10) default null
);
-- 插入数据
insert into employees values ('1', '王昭君', '女', '1003', '开发', '群众', '9');
insert into employees values ('2', '诸葛亮', '男', '1003', '开发经理', '群众', null);
insert into employees values ('3', '张飞', '男', '1002', '测试', '团员', '4');
insert into employees values ('4', '白起', '男', '1002', '测试经理', '党员', null);
insert into employees values ('5', '大乔', '女', '1002', '测试', '党员', '4');
insert into employees values ('6', '孙尚香', '女', '1001', '市场', '党员', '12');
insert into employees values ('7', '百里玄策', '男', '1001', '市场', '团员', '12');
insert into employees values ('8', '小乔', '女', '1002', '测试', '群众', '4');
insert into employees values ('9', '百里守约', '男', '1003', '开发', '党员', '9');
insert into employees values ('10', '妲己', '女', '1003', '开发', '团员', '9');
insert into employees values ('11', '李白', '男', '1002', '测试', '团员', '4');
insert into employees values ('12', '孙膑', '男', '1001', '市场经理', '党员', null);
-- 运行结果
+-------+--------------+------+--------+--------------+-----------------+--------+
| empid | empname | sex | deptid | jobs | politicalstatus | leader |
+-------+--------------+------+--------+--------------+-----------------+--------+
| 1 | 王昭君 | 女 | 1003 | 开发 | 群众 | 9 |
| 2 | 诸葛亮 | 男 | 1003 | 开发经理 | 群众 | NULL |
| 3 | 张飞 | 男 | 1002 | 测试 | 团员 | 4 |
| 4 | 白起 | 男 | 1002 | 测试经理 | 党员 | NULL |
| 5 | 大乔 | 女 | 1002 | 测试 | 党员 | 4 |
| 6 | 孙尚香 | 女 | 1001 | 市场 | 党员 | 12 |
| 7 | 百里玄策 | 男 | 1001 | 市场 | 团员 | 12 |
| 8 | 小乔 | 女 | 1002 | 测试 | 群众 | 4 |
| 9 | 百里守约 | 男 | 1003 | 开发 | 党员 | 9 |
| 10 | 妲己 | 女 | 1003 | 开发 | 团员 | 9 |
| 11 | 李白 | 男 | 1002 | 测试 | 团员 | 4 |
| 12 | 孙膑 | 男 | 1001 | 市场经理 | 党员 | NULL |
+-------+--------------+------+--------+--------------+-----------------+--------+-- 创建工资表
drop table if exists salary;
create table salary (
sid int(10) primary key,
empid int(10) not null,
salary int(10) not null -- 工资
);
-- 插入数据
insert into salary values ('1', '7', '2100');
insert into salary values ('2', '6', '2000');
insert into salary values ('3', '12', '5000');
insert into salary values ('4', '9', '1999');
insert into salary values ('5', '10', '1900');
insert into salary values ('6', '1', '3000');
insert into salary values ('7', '2', '5500');
insert into salary values ('8', '5', '2000');
insert into salary values ('9', '3', '1500');
insert into salary values ('10', '8', '4000');
insert into salary values ('11', '11', '2600');
insert into salary values ('12', '4', '5300');-- 运行结果
+-----+-------+--------+
| sid | empid | salary |
+-----+-------+--------+
| 1 | 7 | 2100 |
| 2 | 6 | 2000 |
| 3 | 12 | 5000 |
| 4 | 9 | 1999 |
| 5 | 10 | 1900 |
| 6 | 1 | 3000 |
| 7 | 2 | 5500 |
| 8 | 5 | 2000 |
| 9 | 3 | 1500 |
| 10 | 8 | 4000 |
| 11 | 11 | 2600 |
| 12 | 4 | 5300 |
+-----+-------+--------+
4.2 案例练习
-- 1、列出总人数大于4的部门号和总人数。(要统计所有部门的人数,需要使用分组, 同时也要使用聚合函数)
select deptid, count(*) from employees group by deptid having count(*)>4;-- 2、列出开发部和和测试部的职工号、姓名
select deptid from departments where deptname in ('开发部','测试部');select empid, empname from employees where deptid in (
select deptid from departments where deptname in ('开发部','测试部')
);-- 3、求出各部门党员的人数,要求显示部门名称。
select * from employees as emp
inner join departments as dep on emp.deptid=dep.deptid
where emp.politicalstatus='党员';select dep.deptname from employees as emp
inner join departments as dep on emp.deptid=dep.deptid
where emp.politicalstatus='党员';select dep.deptname, count(*) from employees as emp
inner join departments as dep on emp.deptid=dep.deptid
where emp.politicalstatus='党员'
group by emp.deptid;-- 4、列出市场部的所有女职工的姓名和政治面貌。
select * from employees as emp
inner join departments as dep on emp.deptid=dep.deptid
where emp.sex='女' and dep.deptname='市场部';select emp.empname, emp.politicalstatus from employees as emp
inner join departments as dep on emp.deptid=dep.deptid
where emp.sex='女' and dep.deptname='市场部';-- 5、显示各部门名和该部门的职工平均工资。
select dep.deptname,avg(sa.salary) from employees as emp
inner join departments as dep on emp.deptid=dep.deptid
inner join salary as sa on sa.empid=emp.empid
group by emp.deptid;-- 6、显示工资最高的前3名职工的职工号和姓名。
select emp.empname, dep.deptname, sa.salary from employees as emp
inner join departments as dep on emp.deptid=dep.deptid
inner join salary as sa on sa.empid=emp.empid
order by sa.salary desc limit 3 -- limit 3 等价于 limit 0, 3-- 7、列出工资在1000-2000之间的所有职工姓名。
select emp.empname, dep.deptname, sa.salary from employees as emp
inner join departments as dep on emp.deptid=dep.deptid
inner join salary as sa on sa.empid=emp.empid
where sa.salary between 1000 and 2000;-- 8、列出工资比王昭君高的员工。(首先查询王昭君的工资)
-- 查询王昭君的工资
select sa.salary from employees as emp
inner join salary as sa on sa.empid=emp.empid
where emp.empname='王昭君';select emp.empname, sa.salary from employees as emp
inner join salary as sa on sa.empid=emp.empid
where sa.salary > (
select sa.salary from employees as emp
inner join salary as sa on sa.empid=emp.empid
where emp.empname='王昭君'
);