子查询

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

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 ...);

相关推荐
WuMingf_几秒前
redis
数据库·redis
张某布响丸辣8 分钟前
SQL中的时间类型:深入解析与应用
java·数据库·sql·mysql·oracle
大懒的猫猫虫9 分钟前
Upload-Labs-Linux1学习笔迹 (图文介绍)
学习
ctrey_35 分钟前
2024-11-13 学习人工智能的Day26 sklearn(2)
人工智能·学习·sklearn
路遇晚风1 小时前
力扣=Mysql-3322- 英超积分榜排名 III(中等)
mysql·算法·leetcode·职场和发展
Allen zhu1 小时前
【PowerHarmony】电鸿蒙学习记录-编写helloworld!
学习·华为·harmonyos
P.H. Infinity1 小时前
【RabbitMQ】10-抽取MQ工具
数据库·分布式·rabbitmq
zgscwxd1 小时前
thinkphp6 --数据库操作 增删改查
数据库·thinkphp6
代码小鑫2 小时前
A031-基于SpringBoot的健身房管理系统设计与实现
java·开发语言·数据库·spring boot·后端