接上篇文章,从这节起:MySQL 5.7 13.2.10.5 Row Subqueries

五、行子查询(ROW Subqueries)

  标量子查询返回单个值,列子查询返回一个列的多个值。而行子查询是子查询变体,它返回单个行,因此可以返回多个列值。

  可用于行子查询比较的操作符如下:

=  >  <  >=  <=  <>  !=  <=>

  以下是两个示例:

SELECT * FROM t1
WHERE (col1,col2) = (SELECT col3, col4 FROM t2 WHERE id = 10); SELECT * FROM t1
WHERE ROW(col1,col2) = (SELECT col3, col4 FROM t2 WHERE id = 10);

  对于这两个查询,如果t2表中有一个id=10的行(仅有一个),则子查询返回这单个行。如果这行数据中的col3、col4两个列的列值与t1表中的任何行的col1、col2相等,则WHERE表达式返回TRUE。两个查询都t1表中的这些行。

  如果t2行col3和col4值不等于任何t1行的col1和col2值,则WHERE表达式为FALSE且查询返回空结果集。

  如果子查询不生成行(空的结果集),则表达式是未知的(即NULL)。如果子查询产生多行,则会发生错误,因为一个行子查询最多只能返回一行。

  有关每个运算符如何进行行比较的信息,see Section 12.3.2, “Comparison Functions and Operators”.

  

  表达式(1,2)和ROW(1,2)有时被称为行构造器。两者是等价的。行构造函数和行子查询返回的行必须包含相同数量的值。

  行构造函数用于与返回两列或更多列的子查询进行比较(只返回一行数据)。当子查询返回单个列时,这被视为标量值而不是行,因此行构造函数不能与不返回至少两列的子查询一起使用。

  因此以下查询会失败并出现语法错误:

SELECT * FROM t1 WHERE ROW(1) = (SELECT column1 FROM t2)

  行构造函数在其他上下文中是合法的。例如,以下两个语句在语义上是等效的(并且由优化器以相同的方式处理):

SELECT * FROM t1 WHERE (column1,column2) = (1,1);
SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;

  以下查询回答请求,“查找表t1中也存在于表t2中的所有行”

SELECT column1,column2,column3
FROM t1
WHERE (column1,column2,column3) IN
(SELECT column1,column2,column3 FROM t2);

  关于优化器和行构造器的更多信息,see Section 8.2.1.19, “Row Constructor Expression Optimization”。

六、具有EXISTS或NOT EXISTS的子查询

  If a subquery returns any rows at all, EXISTS subquery is TRUE, and NOT EXISTS subquery is FALSE.(如果一个子查询返回任何行,那么“EXISTS subquery 会返回TRUE,NOT EXISTS subquery返回FALSE”)

  如下:

SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);

  传统上,EXISTS子查询以SELECT *开头,但它可以从SELECT 5或SELECT column1开始,或者任何东西。因为MySQL忽略了这样一个子查询中的SELECT列表,所以没有区别。

  之前的例子中,如果t2表中有任何数据行,哪怕是全为NULL值的一行数据,那么EXISTS条件判断也会为TRUE。这实际上是一个不太可能出现的例子,因为[NOT] EXISTS子查询几乎总是包含相关性。下面列出了更现实的例子:

  1、一个或多个城市有哪种类型的商店(找出在stores表和cities_stores都存在的
store_type)

SELECT DISTINCT store_type FROM stores
WHERE EXISTS (SELECT * FROM cities_stores
WHERE cities_stores.store_type = stores.store_type);

  2、所有的城市都没有的商店类型是哪种?(找出在stores表和cities_stores都不存在的
store_type)

SELECT DISTINCT store_type FROM stores
WHERE NOT EXISTS (SELECT * FROM cities_stores
WHERE cities_stores.store_type = stores.store_type);

  3、所有城市都有的商店类型是哪种?

SELECT DISTINCT store_type FROM stores s1
WHERE NOT EXISTS (
SELECT * FROM cities WHERE NOT EXISTS (
SELECT * FROM cities_stores
WHERE cities_stores.city = cities.city
AND cities_stores.store_type = stores.store_type));

  最后一个示例是双嵌套的NOT EXISTS查询。也就是说,它在NOT EXISTS子句中还有一个NOT EXISTS子句。在形式上,它回答了这样一个问题——一个城市是否存在在Stores表中不存在的商店?更简单的说法是:嵌套的NOT EXISTS回答了这样的问题——“is x TRUE for all y?”

七、相关子查询(Correlated Subqueries)

  相关子查询是这样一个子查询——在子查询中引用外接查询中的表。

  如下所示:

SELECT * FROM t1
WHERE column1 = ANY (SELECT column1 FROM t2
WHERE t2.column2 = t1.column2);

  请注意,子查询包含对t1表中列的引用,即使子查询的FROM子句未提及表t1。MySQL会在子查询外部查找t1。

  假设t1表有这样一个行:column1=5,column2=6;

  同时,t2表包含这样一个行:column1=5,column2=7;

  此时,WHERE表达式“WHERE column1 = ANY(SELECT column1 FROM t2)”会返回TRUE。但在上面的例子中,子查询中的WHERE子句为FALSE,所以整个子句返回空集,而外部的WHERE表达式总为FALSE。

  范围规则:MySQL会从内到外对语句进行评估。

SELECT column1 FROM t1 AS x
WHERE x.column1 = (SELECT column1 FROM t2 AS x
WHERE x.column1 = (SELECT column1 FROM t3
WHERE x.column2 = t3.column1));

  在这个语句中,x.column2必须是表t2中的一列,因为SELECT column1 FROM t2 AS x ...重命名t2。它不是表t1中的列,因为SELECT column1 FROM t1 ...是一个更远的外部查询。

  对于HAVING或ORDER BY子句中的子查询,MySQL还会在外部的SELECT列表中查找列名。

  

  在某些情况下,相关子查询会被优化掉。例如:

val IN (SELECT key_val FROM tbl_name WHERE correlated_condition)

  否则,它们效率低下并且可能很慢。将查询重写为连接可能会提高性能。

  

  相关子查询中的聚合函数可能包含外部引用,前提是该函数只包含外部引用,并且该函数不包含在另一个函数或表达式中。

MySQL 子查询(二)的更多相关文章

  1. Mysql子查询、关联查询

    mysql中update.delete.install尽量不要使用子查询 一.mysql查询的五种子句         where(条件查询).having(筛选).group by(分组).orde ...

  2. MySQL子查询,派生表和通用表达式

    一:子查询 1.介绍 在另一个查询(外部查询)中嵌套另一个查询语句(内部查询),并使用内部查询的结果值作为外部查询条件. 2.子查询在where中 SELECT customerNumber, che ...

  3. MySQL 子查询(一)

    源自MySQL 5.7 官方手册 13.2.10 Subquery Syntax 〇.MySQL子查询介绍 子查询指的是嵌套在某个语句中的SELECT语句. MySQL支持标准SQL所要求的所有子查询 ...

  4. 第09章 MySQL子查询

    第09章 MySQL子查询 子查询指一个查询语句嵌套在另一个查询语句内部的查询,这个特性从MySQL 4.1开始引入. SQL 中子查询的使用大大增强了 SELECT 查询的能力,因为很多时候查询需要 ...

  5. [慢查优化]慎用MySQL子查询,尤其是看到DEPENDENT SUBQUERY标记时

    案例梳理时间:2013-9-25 写在前面的话: 在慢查优化1和2里都反复强调过 explain 的重要性,但有时候肉眼看不出 explain 结果如何指导优化,这时候还需要有一些其他基础知识的佐助, ...

  6. Mysql子查询IN中使用LIMIT

    学习下Mysql子查询IN中使用LIMIT的方法. 这两天项目里出了一个问题,mysql LIMIT使用后报错. 需求是这样的,我有3张表,infor信息表,mconfig物料配置表,maaply物料 ...

  7. MySQL 子查询 EXISTS 和 NOT EXISTS(转)

    MySQL EXISTS 和 NOT EXISTS 子查询 MySQL EXISTS 和 NOT EXISTS 子查询语法如下: SELECT ... FROM table WHERE EXISTS ...

  8. mysql子查询慢的问题

      当你在用explain工具查看sql语句的运行计划时.若select_type 字段中出现"DEPENDENT SUBQUERY"时,你要注意了.你已经掉入了mysql子查询慢 ...

  9. MySQL子查询慢现象的解决

    当你在用explain工具查看sql语句的执行计划时,若select_type 字段中出现“DEPENDENT SUBQUERY”时,你要注意了,你已经掉入了mysql子查询慢的“坑". 相 ...

  10. MySQL子查询有哪五种形式?

    MySQL是一个关系型数据库管理系统,由瑞典MySQLAB公司开发,目前属于Oracle旗下产品.MySQL是最流行的关系型数据库管理系统之一,在web应用方面,MySQL是最好的RDBMS(Rela ...

随机推荐

  1. Java判断整数溢出

    开题报告第一版写完发给老师了,熬了两周终于搞出来了,等着被怼了之后再改吧.晚上选了Leetcode一道简单的题,整数反转,就是将一个int类型的数反转.原本确实很简单,最后出现个问题有意思--整数溢出 ...

  2. Locust - A modern load testing framework https://locust.io/

    Locust - A modern load testing frameworkhttps://locust.io/

  3. python 设计模式之 (Chain of Responsibility)责任链模式

    #写在前面 对于每一种设计模式,如果不理解它的原理和结构,是写不出例子来的.所以弄明白很重要. 等过完这段浑浑噩噩的日子,我要找个遍地开花的地方开怀大笑一场 #责任链模式定义 简书上一网友就把这个定义 ...

  4. Vue 相关开源项目库汇总

    element ★9395 - 饿了么出品的Vue2的web UI工具套件 Vux ★6835 - 基于Vue和WeUI的组件库 vueAdmin ★569 - 基于vuejs2和element的简单 ...

  5. SQL-W3School-函数:SQL LCASE() 函数

    ylbtech-SQL-W3School-函数:SQL LCASE() 函数 1.返回顶部 1. LCASE() 函数 LCASE 函数把字段的值转换为小写. SQL LCASE() 语法 SELEC ...

  6. TensorFlow Object Detection API —— 测试自己的模型

    (flappbird) luo@luo-All-Series:~/MyFile/TensorflowProject/Mask_RCNN/mask_rcnn_20190518/Mask_RCNN/mod ...

  7. Qt使用boost库

    1.在官网下载boost库 boost_1_70_0.zip 2.将你的Qt的工具目录(有gcc.exe)设置环境变量.(比如F:\Qt592\Tools\mingw530_32\bin) 3.在命令 ...

  8. 【设计】PC Web端框架组件

    https://uedart.com/demo/templatesWebKit/index.html#g=1&p=%E4%BD%9C%E5%93%81%E9%A6%96%E9%A1%B5 移动 ...

  9. laravel中redis pipeline用法说明

    $res = Redis::pipeline(function($pipe) use($params) { for ($i = 0; $i < 1000; $i++) { $pipe->g ...

  10. 第八章 拦截器机制——《跟我学Shiro》

    转发地址:https://www.iteye.com/blog/jinnianshilongnian-2025656 博客分类: 跟我学Shiro 跟我学Shiro  目录贴:跟我学Shiro目录贴 ...