SQL语句(五)子查询
一、子查询含义
出现在其他语句中的select语句,称为子查询或内查询。
二、子查询分类
按子查询的位置分
| 位置 | 支持的查询 |
|---|---|
SELECT后面 |
支持标量子查询 |
FROM后面 |
支持表子查询 |
WHERE或HAVING后面 |
支持标量子查询、列子查询和行子查询 |
EXISTS后面 |
支持表子查询 |
按结果集的行列数不同分
| 分类类型 | 结果集行数 |
|---|---|
| 标量子查询 | 一行一列 |
| 列子查询 | 一列多行 |
| 行子查询 | 一行多列 |
| 表子查询 | 多行多列 |
三、WHERE后面的子查询
1. 标量子查询
tips: 单行操作符(> < =等)只能搭配标量子查询
查询工资比Abel高的所有员工信息
①查询Abel的工资
SELECT salary
FROM employees
WHERE last_name = 'Abel';
结果为单行单列:

②查询员工的信息,满足salary>①

查询公司工资最少的员工的last_name, job_id, salary:
①查询MIN(salary)
SELECT MIN(salary)
FROM employees;
②查询符号这项工资的员工,salary=①
SELECT last_name, job_id, salary
FROM employees
WHERE salary=(
SELECT MIN(salary)
FROM employees
);
查询job_id与141号员工相同,salary比143号员工多的员工的姓名,job_id和工资
①141号员工的job_id
SELECT job_id
FROM employees
WHERE employee_id=141;
②143号员工的salary
SELECT salary
FROM employees
WHERE employee_id=143;
③ 结果集映射到last_name, job_id, salary,且满足条件 job_id=①和salary>②
SELECT last_name, job_id, salary
FROM employees
WHERE job_id=(
SELECT job_id
FROM employees
WHERE employee_id=141
)AND salary>(
SELECT salary
FROM employees
WHERE employee_id=143
);
2. 列子查询(多行子查询)
使用多行操作符:
IN/NOT ININ()等价于=ANY()NOT IN()等价于<>ALL()
ANY/SOMEALL
返回location_id是1400或1700的部门中的所有员工姓名
使用联表查询操作得到结果:
SELECT last_name
FROM departments d INNER JOIN employees e
ON d.department_id = e.department_id
WHERE d.location_id IN (1400, 1700);
使用列子查询得到结果:
①查询location_id是1400或1700的所有部门的编号
SELECT department_id
FROM departments
WHERE location_id IN (1400, 1700);

②查询满足部门编号在列表内的员工的姓名
SELECT last_name
FROM employees
WHERE department_id IN(
SELECT department_id
FROM departments
WHERE location_id IN (1400, 1700)
);
查询其他工种中的
比job_id为IT_PROG工种的任一员工工资低的
员工的:工号,姓名
①获取IT_PROG工种所有工资
SELECT DISTINCT salary
FROM employees
WHERE job_id='IT_PROG'
②查询其他部门中符合条件salary<min(①)的员工信息
SELECT job_id, last_name
FROM employees
WHERE salary < ANY(
SELECT DISTINCT salary
FROM employees
WHERE job_id='IT_PROG'
) AND job_id!='IT_PROG';
3. 行子查询(结果为一行多列或多行多列)
查询员工编号最小而且工资最高的员工信息
①查询最小的员工编号
SELECT MIN(employee_id)
FROM employees;
②查询员工的最高工资
SELECT MAX(salary)
FROM employees;
③查询符合employee_id=①,salary=②的员工
SELECT *
FROM employees
WHERE employee_id=(
SELECT MIN(employee_id)
FROM employees
)AND salary=(
SELECT MAX(salary)
FROM employees
);
使用行子查询的等价写法:
SELECT *
FROM employees
WHERE (employee_id, salary) = (
SELECT MIN(employee_id), MAX(salary)
FROM employees
);
四 、SELECT后面的子查询
查询每个部门的员工个数
使用联表查询操作:
SELECT department_name 部门名, COUNT(1) 员工数量
FROM employees e RIGHT JOIN departments d
ON e.department_id = d.department_id
GROUP BY department_name
使用子查询:
SELECT department_id, department_name,(
SELECT COUNT(1)
FROM employees e
WHERE e.department_id=d.department_id
) 对应员工数
FROM departments d;
在使用子查询中,外部的表名的别名可以传递到子查询中,例如上面的departments 表的别名d就传递到了子查询中。
该子查询可以理解为:
- 先获取
外层查询的结果集 - 然后对结果集的
每条记录进行遍历,将对应的参数填入到子查询中得到单条记录的结果拼接到新列中
五、FROM后面的子查询
查询每个部门的平均工资的工资等级
①查询每个部门的平均工资
SELECT AVG(salary) ag,department_id
FROM employees e
WHERE e.department_id IS NOT NULL
GROUP BY department_id;

②查询对应的工资等级,连接①的结果集和job_grades表
SELECT department_id, ag, grade_level
FROM (
SELECT AVG(salary) ag,department_id
FROM employees e
WHERE e.department_id IS NOT NULL
GROUP BY department_id
) ag_dep INNER JOIN job_grades j
ON ag_dep.ag BETWEEN lowest_sal AND highest_sal;

即可以将子查询的结果集作为一张表用于联表查询操作
六、EXISTS后面的子查询
EXISTS语句的作用
EXISTS语句后的括号中填入一个子查询语句,返回的结果为false(0)或true(1),分别代表查询结果是否为空。
例:
SELECT EXISTS(SELECT employee_id FROM employees);
SELECT EXISTS(SELECT employee_id FROM employees WHERE salary=30000);


简单应用
查询有员工的部门名:
SELECT department_name
FROM departments d
WHERE EXISTS(
SELECT *
FROM employees e
WHERE e.department_id = d.department_id
);
这里等价于用IN
SELECT department_name
FROM departments d
WHERE d.department_id IN(
SELECT DISTINCT department_id
FROM employees
);
查询没有女票的男神信息
使用EXISTS语句
- 查询
男神信息 - 筛选条件:他
没有女票
等价于beauty表中没有boyfriend_id为当前男生的记录
等价于beauty表中boyfriend_id为当前男生的id的记录不存在
SELECT *
FROM boys bo
WHERE NOT EXISTS(
SELECT *
FROM beauty b
WHERE bo.id=b.boyfriend_id
);
使用IN完成相同的任务:
- 查询
男神信息 - 筛选条件:他
没有女票
等价于当前男生的id不在beauty表中boyfriend_id字段的集合中
SELECT *
FROM boys b
WHERE b.id NOT IN(
SELECT boyfriend_id
FROM beauty
);
SQL语句(五)子查询的更多相关文章
- SQL语句:子查询
一,子查询定义: 子查询就是嵌套在主查询中的查询. 子查询可以嵌套在主查询中所有位置,包括SELECT.FROM.WHERE.GROUP BY.HAVING.ORDER BY. 但并不是每个位置嵌套子 ...
- sql 语句 嵌套子查询 执行顺序分析
--创建测试数据create table Student(S# varchar(10),Sname nvarchar(10),Sage datetime,Ssex nvarchar(10))inser ...
- 使用SQL语句的子查询批量复制表数据
批量复制表数据这里有两种方法,下面分别来介绍这两种方法: 一.手动创建新表,然后复制数据 如果是要复制整个表的话,可以使用SQL SERVER自动生成CREATE脚本: 然后在脚本中改改表名就可以了, ...
- TP的一条sql语句(子查询)
$model=M(''); $model->table(C('DB_PREFIX').'goods as g') ->join(C('DB_PREFIX').'orders as o on ...
- sql之独立子查询和相关子查询总结
1.独立子查询:顾名思义:就是子查询和外层查询不存在任何联系,是独立于外层查询的: 下面就看一个例子: 有一张订单表 Sales.Order 和一张 客户表 Sales.Customer 下面的sql ...
- 使用传入的总记录数实现一条sql语句完成分页查询
使用传入的总记录数实现一条sql语句完成分页查询 问题:在传统的分页查询的实现中不可避免的需要两条sql语句,一条用于查询数据一条用于查询总记录数.如下面的实际代码所示: Img1 当然如果使 ...
- mongodb 跟踪SQL语句及慢查询收集
有个需求:跟踪mongodb的SQL语句及慢查询收集 第一步:通过mongodb自带函数可以查看在一段时间内DML语句的运行次数. 在bin目录下面运行 ./mongostat -port 端口号 ...
- [转]在Excel中使用SQL语句实现精确查询
本文转自:http://blog.sina.com.cn/s/blog_5fc375650102e1g5.html 今天在微博上看到@数据分析精选 分享的一篇文章,是关于<在Excel中使用SQ ...
- EXISTS语句的子查询
一.EXISTS运算符简介: 使用EXISTS语句可以测试集合是否为空,EXISTS语句通常与子查询结合在一起使用.只要子查询中至少返回一个值,则EXISTS语句的值就为True.EXISTS子查询的 ...
- 在JDBC中实现SQL语句的模糊查询
在JDBC中实现SQL语句的模糊查询 在大多数情况下我们可以在JDBC中写入sql语句通过占位符的方式来直接查询,但是如果要进行模糊查询,需要转义字符才能够正常查询. sql语句: select * ...
随机推荐
- C++调用Libreoffice接口
由于部分原因,只提供cpp文件,其中代码还需要优化 其中主要涉及了Excel的创建 Sheet页的增加.删除.重命名 表格的合并 表格背景.边框部分属性的设置 表格内字体部分属性设置 表格内容的读取和 ...
- 乘风破浪,遇见下一代操作系统Windows 11,迄今为止最美版本,原生支持安卓应用
遇见下一代操作系统Windows 11 全新Windows体验,让您与热爱的人和事物离得更近. Windows一直是世界创新的舞台.它是全球企业的基石,助力众多蓬勃发展的初创公司变得家喻户晓.网络在W ...
- Linux中的chkconfig
chkconfig是用来查看开机自启动项目的命令.默认列出linux系统开机自启的项目.平时我们使用时习惯加上--list 从这个图中可以看到当前系统有哪些开机启动项目,就是红色框中的on. 那么怎么 ...
- 2.QT浏览器控件设置“透明颜色”
使用样式表或者设置背景颜色,使用 background-color:transparent 但,使用透明的颜色是不可行的: QColor(255,0,0,0)
- C++ nullptr 和 NULL 的使用区别
1. 为什么会有nullptr的出现 目的:nullptr的出现主要是为了替代NULL. 那么,为什么要替代NULL呢? 在NULL的定义中存在会有2种方式,有的编译器会将NULL定义成0,有的编译器 ...
- Ant Design Blazor 组件库的路由复用多标签页介绍
最近,在 Ant Design Blazor 组件库中实现多标签页组件的呼声日益高涨.于是,我利用周末时间,结合 Blazor 内置路由组件实现了基于 Tabs 组件的 ReuseTabs 组件. 前 ...
- POJ 1681 高斯消元 枚举自由变元
题目和poj1222差不多,但是解法有一定区别,1222只要求出任意一解,而本题需要求出最少翻转次数.所以需要枚举自由变元,变元数量为n,则枚举的次数为1<<n次 #include < ...
- Series 1 java秒组合数
Series 1 举几个例子发现, 系数中间对称,很容易想到组合数 c(n,m)==c[n,n-m).此题就是高精度求组合数,java秒之. time:1825ms ,接近时限,如果n还稍微大一 ...
- AcWing 829. 模拟队列
实现一个队列,队列初始为空,支持四种操作: (1) "push x" – 向队尾插入一个数x: (2) "pop" – 从队头弹出一个数: (3) " ...
- Python中的json学习
p.p1 { margin: 0; font: 14px ".PingFang SC"; color: rgba(53, 53, 53, 1) } p.p2 { margin: 0 ...