MySQL数据库子查询#where、from、exists三大类型子查询总结

1.什么是子查询?

当一个查询嵌套了另一个查询,把嵌套在里面的查询先执行的查询就称为子查询。

2.什么情况下会使用到子查询?

当一个查询要完成时,需要用到另一个查询的结果才能继续操作,那么这个查询的select就可以用子查询来方式编写。

测试表一 t_employee(员工表)

下面的栗子都是以此表数据为基准进行子查询操作。

mysql> select *  from t_employee;
+-----+----------+--------+---------+------------+------------+--------------+------+
| eid | ename    | gender | salary  | birthday   | hiredate   | native_place | did  |
+-----+----------+--------+---------+------------+------------+--------------+------+
|   1 | 林大侠        || 8000.46 | 1980-10-08 | 2011-07-28 | 浙江   |    1 |
|   2 | 刘猪猪         || 7000.67 | 1984-08-03 | 2015-07-03 | 河北  |    1 |
|   3 | 猪猪侠         ||    8000 | 1985-04-09 | 2014-07-01 | 陕西    |    1 |
|   4 | 李大象         ||    9456 | 1986-09-07 | 2015-08-08 | 黑龙江  |    3 |
|   5 | 周泡泡         ||    8567 | 1978-08-02 | 2015-01-01 | 吉林    |    1 |
|   6 | 斯瓦辛格        ||   12000 | 1985-04-03 | 2015-02-02 | 内蒙古  |    1 |
|   7 | 乐乐         ||   15700 | 1982-08-02 | 2015-03-03 | 新疆     |   1 |
|   8 | 周大龙        ||    9000 | 1983-03-02 | 2015-01-06 | 西藏     |    1 |
|   9 | 李峰         ||    7897 | 1984-09-01 | 2015-04-01 | 天津     |    1 
|  10 | 韩噶         ||    8789 | 1989-04-02 | 2014-09-03 | 江苏     |    1 |
|  11 | 黄大大        ||   15678 | 1983-05-07 | 2014-04-04 | 安徽   |    1 |
|  12 | 范冰         ||    8909 | 1986-04-02 | 2014-02-08 | 贵州     |    1 
|  13 | 李冰         ||   18760 | 1987-04-09 | 2015-06-07 | 四川       |    1 |
|  14 | 邻娜         ||   18978 | 1990-01-01 | 2015-09-05 | 成都      |    2 |
|  15 | 董号         ||    8978 | 1987-05-05 | 2015-08-04 | 云南     |    2 |
|  16 | 汤唯俄        ||    9878 | 1988-03-06 | 2015-03-06 | 宁夏      |    2 |
|  17 | 李诗圣       ||    9000 | 1990-08-09 | 2013-06-09 | 河南       |    2 |
|  18 | 凯记卡        ||   16788 | 1978-09-04 | 2013-04-05 | 福建      |    4 |
|  19 | 周积极        ||    7876 | 1988-06-13 | 2014-04-07 | 广西      |    4 |
|  20 | 张章子         ||   15099 | 1989-12-11 | 2015-08-04 | 广东     |    5 |
|  21 | 白百客       ||    9787 | 1989-09-04 | 2014-06-05 | 海南      |    5 |
|  22 | 刘化环         ||  130990 | 1990-11-09 | 2016-08-09 | 北京    |    3 |
|  23 | 陈龙         ||  130990 | 1990-02-04 | 2016-05-09 | 上海    |    1 |
|  24 | 迪丽热         ||   10289 | 1990-04-01 | 2017-02-06 | 北京    |    5 |
|  25 | 姚杰杰       ||    9087 | 1989-08-01 | 2017-09-01 | 北京      |    5 |
+-----+----------+--------+---------+------------+------------+--------------+------+
25 rows in set (0.00 sec)

测试表二 t_department(部门表)

mysql> select * from  t_department;
+-----+--------+------------------+
| did | dname  | description      |
+-----+--------+------------------+
|   1 | 开发部       | 负责后台开发工作  |
|   2 | 前端部     | 负责前端开发工作    |
|   3 | 运维部      | 负责服务运营工作   |
|   4 | 客户部      | 负责需求服务工作   |
|   5 | 测试部      | 负责测试工作       |
+-----+--------+------------------+
5 rows in set (0.00 sec)

3.据子查询的嵌入的位置分类:

(1)where型子查询:即把内层的sql语句查询的结果作为外层sql查询的条件。要求子查询的结果是“单个值”或“一列多行”。

①子查询语句要包含在括号中“()”

②一般将子查询放在比较条件的右侧【位置】

③单行操作符对应单行子查询,多行操作符对应多行子查询【操作符-区别】

单行操作符:右边子查询必须返回的是单个值,单行比较运算符(=(等于)、>(大于)、>=(大于等于)、<(小于)、<=(小于等于),<>(不等于))

多行操作符:右边子查询可以返回多行,但是必须是单列,常见有all、any、in,其中all和any必须与单行比较运算符结合使用

操作符小结
操作符说明
in表示任何一个。栗子:num IN(1,2,3)–>判断num是否在1||2||3值中
anyb表示和子查询返回的任意一个值比较。栗子:num>ANY(1,2,3)–>num>1||num>2||num>3
all表示和子查询返回的所有值比较。栗子:num>ALL(1,2,3)–>num>1&&num>2&&num>3
exists表示判断子查询是否有返回值(true/false)

①查询薪资最高的员工和姓名

mysql> SELECT ename FROM t_employee WHERE salary =(SELECT MAX(salary) FROM t_employee);
+--------+
| ename  |
+--------+
| 刘化环       |
| 陈龙       |
+--------+
2 rows in set (0.00 sec)

② 查询和林大侠、周积极他俩的部门编号

mysql> SELECT did FROM t_employee WHERE ename IN ('林大侠','周积极');
+------+
| did  |
+------+
|    1 |
|    4 |
+------+
2 rows in set (0.00 sec)

③查询其他员工,编号和林大侠、周积他俩一样

mysql> SELECT * FROM t_employee WHERE did 
IN (SELECT did FROM t_employee WHERE ename IN ('林大侠','周积极'));
+-----+----------+--------+---------+------------+------------+--------------+------+
| eid | ename    | gender | salary  | birthday   | hiredate   | native_place | did  |
+-----+----------+--------+---------+------------+------------+--------------+------+
|   1 | 林大侠        || 8000.46 | 1980-10-08 | 2011-07-28 | 浙江    |    1 |
|   2 | 刘猪猪         || 7000.67 | 1984-08-03 | 2015-07-03 | 河北   |    1 |
|   3 | 猪猪侠         ||    8000 | 1985-04-09 | 2014-07-01 | 陕西   |    1 |
|   5 | 周泡泡         ||    8567 | 1978-08-02 | 2015-01-01 | 吉林   |    1 |
|   6 | 斯瓦辛格        ||   12000 | 1985-04-03 | 2015-02-02 | 内蒙古 |    1 
|   7 | 乐乐         ||   15700 | 1982-08-02 | 2015-03-03 | 新疆    |    1 |
|   8 | 周大龙        ||    9000 | 1983-03-02 | 2015-01-06 | 西藏    |    1 |
|   9 | 李峰         ||    7897 | 1984-09-01 | 2015-04-01 | 天津    |    1 |
|  10 | 韩噶         ||    8789 | 1989-04-02 | 2014-09-03 | 江苏    |    1 |
|  11 | 黄大大        ||   15678 | 1983-05-07 | 2014-04-04 | 安徽   |    1 |
|  12 | 范冰         ||    8909 | 1986-04-02 | 2014-02-08 | 贵州    |    1
|  13 | 李冰         ||   18760 | 1987-04-09 | 2015-06-07 | 四川    |    1 |
|  18 | 凯记卡        ||   16788 | 1978-09-04 | 2013-04-05 | 福建   |    4 |
|  19 | 周积极        ||    7876 | 1988-06-13 | 2014-04-07 | 广西    |    4 |
|  23 | 陈龙         ||  130990 | 1990-02-04 | 2016-05-09 | 上海    |    1 |
+-----+----------+--------+---------+------------+------------+--------------+------+
15 rows in set (0.00 sec)

④查询林大侠、李大象、张章子他们三个薪资

mysql> SELECT salary FROM t_employee WHERE ename IN('林大侠','李大象','张章子');
+---------+
| salary  |
+---------+
| 8000.46 |
|    9456 |
|   15099 |
+---------+
3 rows in set (0.00 sec)

⑤查询比林大侠、李大象、张章子他们的薪资都高的员工

mysql> SELECT * FROM t_employee WHERE salary >ALL(SELECT salary FROM t_employee WHERE ename IN('林大侠','李大象','张章子'));
+-----+--------+--------+--------+------------+------------+--------------+------+
| eid | ename  | gender | salary | birthday   | hiredate   | native_place | did  |
+-----+--------+--------+--------+------------+------------+--------------+------+
|   7 | 乐乐       ||  15700 | 1982-08-02 | 2015-03-03 | 新疆       |    1 |
|  11 | 黄大大      ||  15678 | 1983-05-07 | 2014-04-04 | 安徽       |    1 |
|  13 | 李冰       ||  18760 | 1987-04-09 | 2015-06-07 | 四川        |    1 |
|  14 | 邻娜       ||  18978 | 1990-01-01 | 2015-09-05 | 成都         |    2 |
|  18 | 凯记卡      ||  16788 | 1978-09-04 | 2013-04-05 | 福建         |    4 |
|  22 | 刘化环       || 130990 | 1990-11-09 | 2016-08-09 | 北京        |    3 |
|  23 | 陈龙       || 130990 | 1990-02-04 | 2016-05-09 | 上海         |    1 |
+-----+--------+--------+--------+------------+------------+--------------+------+
7 rows in set (0.00 sec)

(2)from型子查询:即把内层sql语句查询的结果作为临时表供外层sql语句再次查询。

① 查询部门编号、部门的名称、部门的平均工资

mysql> SELECT did,AVG(salary) FROM t_employee GROUP BY did;
+------+--------------------+
| did  | AVG(salary)        |
+------+--------------------+
|    1 | 19945.471538461537 |
|    2 |            11708.5 |
|    3 |              70223 |
|    4 |              12332 |
|    5 |            11065.5 |
+------+--------------------+
5 rows in set (0.00 sec)

②用子查询的结果当做一张临时表和部门表进行联合查询
给子查询的结果,取别名,当做临时表
给分组函数的计算结果列取别名,当做一个普通的列使用

mysql> SELECT temp.did,dname,temp.pingjun
    -> FROM (SELECT did,AVG(salary) AS pingjun FROM t_employee GROUP BY did) AS temp
    -> INNER JOIN t_department ON temp.did =t_department.`did`;
+------+--------+--------------------+
| did  | dname  | pingjun            |
+------+--------+--------------------+
|    1 | 开发部       | 19945.471538461537 |
|    2 | 前端部     |            11708.5 |
|    3 | 运维部      |              70223 |
|    4 | 客户部      |              12332 |
|    5 | 测试部      |            11065.5 |
+------+--------+--------------------+
5 rows in set (0.00 sec)

(3)exists型子查询

查询有员工的部门

mysql> SELECT did,dname,description FROM t_department WHERE EXISTS
    -> (SELECT * FROM t_employee WHERE t_employee.did=t_department.`did`);
+-----+--------+------------------+
| did | dname  | description      |
+-----+--------+------------------+
|   1 | 开发部       | 负责后台开发工作                |
|   2 | 前端部     | 负责前端开发工作               |
|   3 | 运维部      | 负责服务运营工作                |
|   4 | 客户部      | 负责需求服务工作                 |
|   5 | 测试部      | 负责测试工作                |
+-----+--------+------------------+
5 rows in set (0.00 sec)
#轻松一刻:

在这里插入图片描述


  ☝上述分享来源个人总结,如果分享对您有帮忙,希望您积极转载;如果您有不同的见解,希望您积极留言,让我们一起探讨,您的鼓励将是我前进道路上一份助力,非常感谢!我会不定时更新相关技术动态,同时我也会不断完善自己,提升技术,希望与君同成长同进步!

☞本人博客:https://coding0110lin.blog.csdn.net/  欢迎转载,一起技术交流吧!

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值