子查询

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

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

相关推荐
Elastic 中国社区官方博客3 小时前
在 Elasticsearch 中使用 Mistral Chat completions 进行上下文工程
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
容器( ु⁎ᴗ_ᴗ⁎)ु.。oO4 小时前
Magentic-ui 学习
学习
_李小白4 小时前
【OPENGL ES 3.0 学习笔记】延伸阅读:VAO与VBO
笔记·学习·elasticsearch
编程爱好者熊浪5 小时前
两次连接池泄露的BUG
java·数据库
南宫乘风6 小时前
基于 Flask + APScheduler + MySQL 的自动报表系统设计
python·mysql·flask
微露清风6 小时前
系统性学习C++-第九讲-list类
c++·学习·list
海边夕阳20066 小时前
【每天一个AI小知识】:什么是零样本学习?
人工智能·经验分享·学习
TDengine (老段)6 小时前
TDengine 字符串函数 CHAR 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
qq7422349846 小时前
Python操作数据库之pyodbc
开发语言·数据库·python
姚远Oracle ACE7 小时前
Oracle 如何计算 AWR 报告中的 Sessions 数量
数据库·oracle