一、子查询含义

出现在其他语句中的select语句,称为子查询内查询

二、子查询分类

按子查询的位置分

位置 支持的查询
SELECT后面 支持标量子查询
FROM后面 支持表子查询
WHEREHAVING后面 支持标量子查询列子查询行子查询
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 IN

    • IN()等价于=ANY() NOT IN()等价于<>ALL()
  • ANY/SOME
  • ALL

返回location_id1400或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_id1400或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_idIT_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就传递到了子查询中。

该子查询可以理解为:

  1. 先获取外层查询的结果集
  2. 然后对结果集的每条记录进行遍历,将对应的参数填入到子查询中得到单条记录的结果拼接到新列中

五、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语句

  1. 查询男神信息
  2. 筛选条件:他没有女票

    等价于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完成相同的任务:

  1. 查询男神信息
  2. 筛选条件:他没有女票

    等价于当前男生的id不在beauty 表中boyfriend_id字段的集合中
SELECT *
FROM boys b
WHERE b.id NOT IN(
SELECT boyfriend_id
FROM beauty
);

SQL语句(五)子查询的更多相关文章

  1. SQL语句:子查询

    一,子查询定义: 子查询就是嵌套在主查询中的查询. 子查询可以嵌套在主查询中所有位置,包括SELECT.FROM.WHERE.GROUP BY.HAVING.ORDER BY. 但并不是每个位置嵌套子 ...

  2. sql 语句 嵌套子查询 执行顺序分析

    --创建测试数据create table Student(S# varchar(10),Sname nvarchar(10),Sage datetime,Ssex nvarchar(10))inser ...

  3. 使用SQL语句的子查询批量复制表数据

    批量复制表数据这里有两种方法,下面分别来介绍这两种方法: 一.手动创建新表,然后复制数据 如果是要复制整个表的话,可以使用SQL SERVER自动生成CREATE脚本: 然后在脚本中改改表名就可以了, ...

  4. TP的一条sql语句(子查询)

    $model=M(''); $model->table(C('DB_PREFIX').'goods as g') ->join(C('DB_PREFIX').'orders as o on ...

  5. sql之独立子查询和相关子查询总结

    1.独立子查询:顾名思义:就是子查询和外层查询不存在任何联系,是独立于外层查询的: 下面就看一个例子: 有一张订单表 Sales.Order 和一张 客户表 Sales.Customer 下面的sql ...

  6. 使用传入的总记录数实现一条sql语句完成分页查询

    使用传入的总记录数实现一条sql语句完成分页查询     问题:在传统的分页查询的实现中不可避免的需要两条sql语句,一条用于查询数据一条用于查询总记录数.如下面的实际代码所示: Img1 当然如果使 ...

  7. mongodb 跟踪SQL语句及慢查询收集

    有个需求:跟踪mongodb的SQL语句及慢查询收集 第一步:通过mongodb自带函数可以查看在一段时间内DML语句的运行次数. 在bin目录下面运行  ./mongostat -port 端口号  ...

  8. [转]在Excel中使用SQL语句实现精确查询

    本文转自:http://blog.sina.com.cn/s/blog_5fc375650102e1g5.html 今天在微博上看到@数据分析精选 分享的一篇文章,是关于<在Excel中使用SQ ...

  9. EXISTS语句的子查询

    一.EXISTS运算符简介: 使用EXISTS语句可以测试集合是否为空,EXISTS语句通常与子查询结合在一起使用.只要子查询中至少返回一个值,则EXISTS语句的值就为True.EXISTS子查询的 ...

  10. 在JDBC中实现SQL语句的模糊查询

    在JDBC中实现SQL语句的模糊查询 在大多数情况下我们可以在JDBC中写入sql语句通过占位符的方式来直接查询,但是如果要进行模糊查询,需要转义字符才能够正常查询. sql语句: select * ...

随机推荐

  1. AS打包签名

    1.进入项目,然后点击菜单栏的Build  -->Generate  Signed APK... (如下图所示) 2.点击之后会出现下图,我这个是我以前有过KEY了,如果你以前没有过的话,都是空 ...

  2. 如何利用Python计算景观指数AI

    可使用工具包 pylandstats 此工具包基本是根据fragstats形成的,大部分fragstats里面的景观指数,这里都可以计算.但是,还是有一小部分指数这里没有涉及. LS_METRICS ...

  3. 让Qt5默认支持C++17的设置方法

    单个项目的设置方法 打开项目的 pro 文件,将CONFIG += console c++11改为CONFIG += console c++17即可. 永久默认支持 c++17 的设置方法 找到 Qt ...

  4. Docker入门与进阶(下)

    Docker入门与进阶(下) 作者 刘畅 时间 2020-11-12 实验主机配置 系统centos7.5 主机名 ip 配置 应用 harbor-master 172.16.1.71 2核4G/60 ...

  5. C++智能指针之shared_ptr与右值引用(详细)

    1. 介绍 在 C++ 中没有垃圾回收机制,必须自己释放分配的内存,否则就会造成内存泄露.解决这个问题最有效的方法是使用智能指针(smart pointer).智能指针是存储指向动态分配(堆)对象指针 ...

  6. Docker下的mysql安装指令(Mac)

    工具   简介 对于Docker,绝对是开发人员的一款利器!当下特别火热的虚拟化技术.都说不知Docker是什么,作为IT人就out了. 关于Docker 是什么.及其基础学习可以参考: <Do ...

  7. python自定义异常,使用raise引发异常

    1.自定义异常类,自定义的异常类必须是Exception或者Error的子类! 1 #!/usr/bin/env python 2 # encoding: utf-8 3 4 class Illega ...

  8. Redis的内存回收原理,及内存过期淘汰策略详解

    Redis 内存回收机制Redis 的内存回收主要围绕以下两个方面: 1.Redis 过期策略:删除过期时间的 key 值 2.Redis 淘汰策略:内存使用到达 maxmemory 上限时触发内存淘 ...

  9. IT面试最全逻辑题,收藏后成功率提高10%

    这是小学二年级的数学题: 猫妈妈钓到一些鱼,平均分给了7只小猫,每只小猫分到的鱼和剩下的鱼刚好一样多.猫妈妈最多钓到了多少条鱼? 这个是出来工作后的现场面试题: [1]假设有一个池塘,里面有无穷多的水 ...

  10. ESP32-使用ADC笔记

    基于ESP-IDF4.1 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include "freertos/FreeRT ...