子查询

子查询与多表连接查询的抉择

1.当连接的两个表中的记录很多时,笛卡尔积运算会造成死机。于是如果要用join语句连接查询,可以先查看涉及到的表的记录数。利用统计记录行数的函数count()查看所关联的表笛卡尔积后的行数:select count(*) from 表1,表2;

2.如果查到的记录数不算太大,则可进行多表连接查询。否则,如果数据量太大的话,应选用子查询的方式。

  1. 子查询的SQL写法比连接查询的写法复杂,常用到in、any、all和exists等关键字,和比较运算符。

  2. Where子句中的子查询,一般返回单行单列、多行单行或单行多列数据记录。

  3. from子句中的子查询,一般返回多行多列数据记录,可以当作一张临时表。

一、理解子查询

子查询也称为嵌套查询(Nested Query),即是嵌套在外层查询的WHERE子句中的查询,有时也会嵌套在HAVING的条件中或from子句中。子查询为主查询返回其所需数据, 或者对外查询的查询结果作进一步的限制。每一个SELECT-FROM-WHERE语句称为一个查询块.

SELECT ... FROM 表名 --- 主査询,外层查询

WHERE

(SELECT ... FROM table WHERE ...);--- 子査询,内层査询

即where条件中又有select语句,称为子查询或嵌套查询

二、使用关系运算符和带IN的子查询

内层查询返回列col_name的值,然后外层查询意义相同的列colname和子查询的返回值做比较。使用关系运算符(可以是=、<、<=、>、>=、!=、<>) 时,子查询的返回值至多一个;当使用IN时,子查询的返回值可以有多个。

SELECT ... FROM 表名1

WHERE 列名col_name 关系运算符 | IN | NOT IN

(SELECT 列名col_name FROM 表名2 WHERE ...);

三、单行子查询:

单行子查询包括单行单列子查询和单行多列子查询。可用>、 <、 =和!=连接后边子查询,要求括号中返回的结果为某单一值。

1.单行单列子查询

子查询一般会在主查询语句的Where子句中。

单行单列子查询,也称为稀疏子查询 稀疏子查询是期待在子查询中单一返回值的嵌套查询

2.单行多列子查询

子查询中可以返回单行多列的数据记录,但此类子查询用途较少。

四、多行子查询:

1、多行单列子查询

多行单列子查询可用in, not in来连接后边的子查询,括号中返回的结果为多个值(的集合)。

多行子查询包括多行单列子查询和多行多列子查询。

(1). 带有关键字in的子查询:

当主查询的条件是子查询的结果中的值时,就可以通过关键字in来进行判断。相反当主查询的条件不是子查询的结果中的值时,就可以通过关键字 not in来进行判断。

(2). 带有关键字not in的子查询:

带in的子查询总结

1.带in的子查询中,内查询和外查询必须使用意义相同的字段来构造条件;

  1. 如果内查询的结果只有一个返回值,则可以用关系运算符或者in来构造条件;

  2. 如果内查询的结果有多个返回值,则必须只能用in来构造条件。

带ANY、SOME、ALL的子查询

使用带some、any或all的子查询来构造查询条件时,some、any或all的前面必须加上关系运算符,

如大于、等于或小于等。

ANY 和 SOME 同义,为某个之意。在进行比较运算时只要子查询的查询结果 中有某一行能使结果为 True, 则子查询结果就为True;

而ALL则要求子查询中的所有行都使结果为 True 时,子查询结果才为 True。

SELECT 字段名 FROM 表名1

WHERE 字段名 关系运算符 [ANY | SOME | ALL]

(SELECT 字段名 FROM 表名2 WHERE ...);

注:关系运算符可以是<=、<、=、>、>=、!=、<>。

(3). 带有关键字any的子查询:

当主查询的条件是满足子查询的结果中的某条记录时,用带有关键字any的子查询。关键字any或some有三种匹配方式,分别为:

① = any:其功能与关键字in一样;

② > any(或>= any):为大于(或>=)子查询中返回数据中某个即可 ;即比子查询中返回数据记录中最小的要大(或>=);

③ < any (或<= any):为小于(或<=)子查询中返回数据中某个即可 ;即比子查询中返回数据记录中最大的要小(或<=) ;

(4). 带有关键字some 的子查询:

关键字some与any完全相同,有三种匹配方式,分别为:

① > some (或>=some):为大于(或>=)子查询中返回数据中的某个 ;即比子查询中返回数据记录中最小的大(或>=)即可;

② <some (或<= some ):为小于(或<=)子查询中返回数据中的某个;即比子查询中返回数据记录中最大的小(或<=)即可;

③ = some:为子查询中返回数据中某一个。

(5). 带有关键字all 的子查询:

当主查询的条件是满足子查询的结果中的所有记录时,可用带有关键字all的子查询。

关键字all 有两种匹配方式,分别为:

① > all (或>= all):为大于(或>=)子查询中返回数据中所有的 ;即比子查询中返回数据记录中最大的还要大于(或>=)的数据记录 ;

②< all (或<= all ):为小于(或<=)子查询中返回数据中所有的;即比子查询中返回数据记录中最小的还要小(或<=)的数据记录 ;

(6).带有关键字exists 的子查询:

EXISTS (一个子查询),是检测子查询的行是否存在数据,即子查询的结果是不是空集。

SELECT... . FROM table WHERE EXISTS (subquery)

EXISTS 用于检查子查询是否至少会返回一行数据,该子查询实际上并不取返回的任何数据,而是要返回值True或False 。将主查询的数据,放到子查询中做条件验证,根据验证结果(TRUE或FALSE )来决定主查询的数据结果是否得以保留。.在子查询中使用 NULL 仍然返回结果集,通过使用 EXISTS 仍取值为 TRUE。

subquery 是一个受限的SELECT 语句(不允许有COMPUTE 子句和INTO关键字)。如果子查询至少包含一行,则返回TRUE。

如果子查询有元组,即非空,则exists 返回true

exists r  r ≠ Ø not exists r  r = Ø

  1. 带exists的子查询,只检查子查询中有没有结果返回。如果是空集则不执行,如果有值,则执行。
  2. 子查询的结果并不参与比较,所以exists的前面不加任何关系运算符(如大于、等于或小于等)。

2、多行多列子查询:

当子查询的返回结果为多行多列数据记录时,该子查询语句一般会在主查询语句的from子句里,被当作一张临时表的方式来处理。

五、带 EXISTS 的子查询

EXISTS 用来检查子查询是否至少会返回一行数据, 该子查询实际上并不取返回的任何数据, 而是要返回值True或False。只要返回一行, EXISTS 的结果即为 True, 外查询语句执行查询;反之如果返回空集,则结果为 False, 此时外层查询语句将不执行。

将主查询的数据,放到子查询中做条件验证,根据验证结果TRUE或 FALSE)来决定主查询的数据结果是否得以保留。也就是说EXISTS 的意思是子查询中是否存在结果。如果存在则主查询的where条件成立,如果不存在则主查询的where条件不成立。

SELECT 字段名 FROM 表名1

WHERE [EXISTS | NOT EXISTS]

(SELECT ... FROM表名2 WHERE ...);

相关推荐
wusixuan13100424 分钟前
最大闭合子图学习笔记 / P2805 [NOI2009] 植物大战僵尸
笔记·学习·算法·最大闭合子图
xx155802862xx30 分钟前
centos转移mysql的数据存储目录
linux·mysql·centos
进击的CJR32 分钟前
MySQL 8.0 OCP 英文题库解析(十五)
数据库·mysql·开闭原则
羊小猪~~38 分钟前
数据库学习笔记(十五)--变量与定义条件与处理程序
数据库·人工智能·笔记·后端·sql·学习·mysql
梦境虽美,却不长44 分钟前
数据结构 线性表 学习 2025/6/12 21点27分
数据结构·学习
正在努力Coding1 小时前
MongoDB详细安装步骤(Windows 系统)
数据库·mongodb
TDengine (老段)1 小时前
TDengine 基础功能——数据写入
大数据·数据库·物联网·oracle·时序数据库·tdengine·涛思数据
霸王蟹1 小时前
带你手写React中的useReducer函数。(底层实现)
前端·javascript·笔记·学习·react.js·typescript·前端框架
Humbunklung1 小时前
分布假设学习笔记
笔记·深度学习·学习
fie88892 小时前
MySQL:Prepared Statement 预处理语句
android·数据库·mysql