select 高级查询之子查询
时间:2022-07-26
本文章向大家介绍select 高级查询之子查询,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1.1 概述
在 SQL 语言中,一个 SELECT-FROM-WHERE 语句称为一个查询块。当获得一个查询的答案需要多个步骤的操作,首先必须创建一个查询来确定用户不知道但包含在数据库中的值,将一个查询块嵌套在另一个查询块的 WHERE 字句或 HAVING 短语的条件中查询块称为子查询或内层查询。外部的 SELECT 查询语句,称为主查询或外查询。按结果集的行列数不同子查询可以分为 4 种 ♞ 标量子查询(结果集只有一行一列) ♞ 列子查询(结果集只有一列多行) ♞ 行子查询(结果集有一行多列) ♞ 表子查询(结果集一般为多行多列)
1.2 数据准备
# 员工表
mysql> select * from emp;
+------+--------+--------+------+------------+----------+----------+---------+
| id | ename | job_id | mgr | joindate | salary | bonus | dept_id |
+------+--------+--------+------+------------+----------+----------+---------+
| 1001 | 孙悟空 | 4 | 1004 | 2000-12-17 | 8000.00 | NULL | 20 |
| 1002 | 卢俊义 | 3 | 1006 | 2001-02-20 | 16000.00 | 3000.00 | 30 |
| 1003 | 林冲 | 3 | 1006 | 2001-02-22 | 12500.00 | 5000.00 | 30 |
| 1004 | 唐僧 | 2 | 1009 | 2001-04-02 | 29750.00 | NULL | 20 |
| 1005 | 李逵 | 4 | 1006 | 2001-09-28 | 12500.00 | 14000.00 | 30 |
| 1006 | 宋江 | 2 | 1009 | 2001-05-01 | 28500.00 | NULL | 30 |
| 1007 | 刘备 | 2 | 1009 | 2001-09-01 | 24500.00 | NULL | 10 |
| 1008 | 猪八戒 | 4 | 1004 | 2007-04-19 | 30000.00 | NULL | 20 |
| 1009 | 罗贯中 | 1 | NULL | 2001-11-17 | 50000.00 | NULL | 10 |
| 1010 | 吴用 | 3 | 1006 | 2001-09-08 | 15000.00 | 0.00 | 30 |
| 1011 | 沙僧 | 4 | 1004 | 2007-05-23 | 11000.00 | NULL | 20 |
| 1012 | 李逵 | 4 | 1006 | 2001-12-03 | 9500.00 | NULL | 30 |
| 1013 | 小白龙 | 4 | 1004 | 2001-12-03 | 30000.00 | NULL | 20 |
| 1014 | 关羽 | 4 | 1007 | 2002-01-23 | 13000.00 | NULL | 10 |
+------+--------+--------+------+------------+----------+----------+---------+
14 rows in set (0.15 sec)
# 部门信息表
mysql> select * from dept;
+----+--------+------+
| id | dname | loc |
+----+--------+------+
| 10 | 教研部 | 北京 |
| 20 | 学工部 | 上海 |
| 30 | 销售部 | 广州 |
| 40 | 财务部 | 深圳 |
+----+--------+------+
4 rows in set (0.15 sec)
# 工作职责表
mysql> select * from job;
+----+--------+--------------------+
| id | jname | description |
+----+--------+--------------------+
| 1 | 董事长 | 管理整个公司,接单 |
| 2 | 经理 | 管理部门员工 |
| 3 | 销售员 | 向客人推销产品 |
| 4 | 文员 | 使用办公软件 |
+----+--------+--------------------+
4 rows in set (0.16 sec)
# 薪资等级表
mysql> select * from salarygrade;
+-------+----------+----------+
| grade | losalary | hisalary |
+-------+----------+----------+
| 1 | 7000 | 12000 |
| 2 | 12010 | 14000 |
| 3 | 14010 | 20000 |
| 4 | 20010 | 30000 |
| 5 | 30010 | 99990 |
+-------+----------+----------+
5 rows in set (0.14 sec)
1.3 select 后的子查询
1.3.1 查询每个部门员工个数
mysql> select dept.*,
-> ( select count(*) from emp where emp.dept_id = dept.id ) as 员工个数
-> from dept;
+----+--------+------+----------+
| id | dname | loc | 员工个数 |
+----+--------+------+----------+
| 10 | 教研部 | 北京 | 3 |
| 20 | 学工部 | 上海 | 5 |
| 30 | 销售部 | 广州 | 6 |
| 40 | 财务部 | 深圳 | 0 |
+----+--------+------+----------+
4 rows in set (2.02 sec)
1.3.2 查询 1002 号员工的姓名和部门名称
mysql> select ename as 姓名,
-> (select dname from dept where emp.dept_id = dept.id) as 部门名
-> from emp
-> where id = 1002;
+--------+--------+
| 姓名 | 部门名 |
+--------+--------+
| 卢俊义 | 销售部 |
+--------+--------+
1 row in set (0.15 sec)
1.4 from 后的子查询
1.4.1 查询每个部门的平均工资
mysql> select avg(salary) as avg, dept_id from emp group by dept_id;
+--------------+---------+
| avg | dept_id |
+--------------+---------+
| 29166.666667 | 10 |
| 21750.000000 | 20 |
| 15666.666667 | 30 |
+--------------+---------+
3 rows in set (0.11 sec)
mysql> select dept.dname as 部门, t.avg as 平均工资 from
-> ( select avg(salary) as avg, dept_id from emp group by dept_id ) as t, dept
-> where t.dept_id = dept.id;
+--------+--------------+
| 部门 | 平均工资 |
+--------+--------------+
| 教研部 | 29166.666667 |
| 学工部 | 21750.000000 |
| 销售部 | 15666.666667 |
+--------+--------------+
3 rows in set (0.18 sec)
1.5 where 后的子查询
1.5.1 查询工资高于 30 号部门平均工资的员工信息
mysql> select avg(salary) from emp where dept_id = 30;
+--------------+
| avg(salary) |
+--------------+
| 15666.666667 |
+--------------+
1 row in set (0.10 sec)
mysql> select * from emp where ( select avg(salary) from emp where dept_id = 30 ) < salary;
+------+--------+--------+------+------------+----------+---------+---------+
| id | ename | job_id | mgr | joindate | salary | bonus | dept_id |
+------+--------+--------+------+------------+----------+---------+---------+
| 1002 | 卢俊义 | 3 | 1006 | 2001-02-20 | 16000.00 | 3000.00 | 30 |
| 1004 | 唐僧 | 2 | 1009 | 2001-04-02 | 29750.00 | NULL | 20 |
| 1006 | 宋江 | 2 | 1009 | 2001-05-01 | 28500.00 | NULL | 30 |
| 1007 | 刘备 | 2 | 1009 | 2001-09-01 | 24500.00 | NULL | 10 |
| 1008 | 猪八戒 | 4 | 1004 | 2007-04-19 | 30000.00 | NULL | 20 |
| 1009 | 罗贯中 | 1 | NULL | 2001-11-17 | 50000.00 | NULL | 10 |
| 1013 | 小白龙 | 4 | 1004 | 2001-12-03 | 30000.00 | NULL | 20 |
+------+--------+--------+------+------------+----------+---------+---------+
7 rows in set (0.16 sec)
1.5.2 查询有工资高于 29000 的部门
mysql> select dept_id from emp where salary > 29000 group by dept_id;
+---------+
| dept_id |
+---------+
| 10 |
| 20 |
+---------+
2 rows in set (0.11 sec)
mysql> select dname as 部门名
-> from dept
-> where id in (select dept_id from emp where salary > 29000 group by dept_id);
+--------+
| 部门名 |
+--------+
| 学工部 |
| 教研部 |
+--------+
2 rows in set (0.14 sec)
1.5.3 查询部门号最小,工资最高的员工信息
mysql> select min(dept_id), max(salary) from emp;
+--------------+-------------+
| min(dept_id) | max(salary) |
+--------------+-------------+
| 10 | 50000.00 |
+--------------+-------------+
1 row in set (0.11 sec)
mysql> select * from emp where (dept_id, salary) = (select min(dept_id), max(salary) from emp);
+------+--------+--------+------+------------+----------+-------+---------+
| id | ename | job_id | mgr | joindate | salary | bonus | dept_id |
+------+--------+--------+------+------------+----------+-------+---------+
| 1009 | 罗贯中 | 1 | NULL | 2001-11-17 | 50000.00 | NULL | 10 |
+------+--------+--------+------+------------+----------+-------+---------+
1 row in set (19.54 sec)
1.6 注意
① 子查询放在小括号内,且一般放在条件的右侧。 ② 标量子查询,一般搭配着单行操作符使用,列子查询,一般搭配着多行操作符使用。 ③ 子查询的执行优先于主查询执行,因为主查询的条件用到了子查询的结果。 ④ select 后面的子查询,仅仅支持标量子查询,即结果集只有一行一列。 ⑤ from 后面的子查询是将子查询的结果集充当一张临时表,要求必须起别名,否者这个表找不到。然后将真实的表和子查询结果表进行连接查询。 ⑥ where 或 having 后面可以有:标量子查询、 列子查询(一般搭配着多行操作符使用 in、any、some、all 等)、行子查询。
- Mysql+Keepalived双主热备高可用操作记录
- Mysql双主热备+LVS+Keepalived高可用操作记录
- 被曝大裁员!曲德君坚称万达网科没有倒下、目标决心不变
- Linux下smokeping网络监控环境部署记录
- Linux下的rsyslog系统日志梳理(用户操作记录审计)
- 数据结构之数组封装
- Centos下内网NDS主从环境部署记录
- 一搜解决,微信的这个功能厉害了!
- Saltstack自动化操作记录(2)-配置使用
- Saltstack自动化操作记录(1)-环境部署
- CentOS源码编译安装Nginx和tcp_proxy module
- 介绍一个MonoTouch开发的伦敦官方城市指南应用
- 虾说区块链-55-《精通比特币》笔记十
- SignalR QuickStart
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- JavaScript 异步编程
- R海拾遗-图片拼接
- 基于SSH框架的人力资源管理系统设计与实现
- Flutter/Dart中的异步
- UTM坐标的遥感图,Python终于把它扶正啦(手动狗头)
- Flutter框架分析(一)-- 总览和Window
- R海拾遗-sci配色
- Flutter框架分析(二)-- 初始化
- Flutter框架分析(三)-- Widget,Element和RenderObject
- 傅里叶变换的图像应用--学好了用处大~
- Flutter框架分析(四)-- Flutter框架的运行
- R海拾遗-流程图prismadiagramR
- R海拾遗-单项重复测量方差分析
- R海拾遗-双因素重复测量方差分析
- 小白秒变大神--windows窗口+装B神器大全 两部曲