MySQL 子查询(二)
接上篇文章,从这节起: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 子查询(二)的更多相关文章
- Mysql子查询、关联查询
mysql中update.delete.install尽量不要使用子查询 一.mysql查询的五种子句 where(条件查询).having(筛选).group by(分组).orde ...
- MySQL子查询,派生表和通用表达式
一:子查询 1.介绍 在另一个查询(外部查询)中嵌套另一个查询语句(内部查询),并使用内部查询的结果值作为外部查询条件. 2.子查询在where中 SELECT customerNumber, che ...
- MySQL 子查询(一)
源自MySQL 5.7 官方手册 13.2.10 Subquery Syntax 〇.MySQL子查询介绍 子查询指的是嵌套在某个语句中的SELECT语句. MySQL支持标准SQL所要求的所有子查询 ...
- 第09章 MySQL子查询
第09章 MySQL子查询 子查询指一个查询语句嵌套在另一个查询语句内部的查询,这个特性从MySQL 4.1开始引入. SQL 中子查询的使用大大增强了 SELECT 查询的能力,因为很多时候查询需要 ...
- [慢查优化]慎用MySQL子查询,尤其是看到DEPENDENT SUBQUERY标记时
案例梳理时间:2013-9-25 写在前面的话: 在慢查优化1和2里都反复强调过 explain 的重要性,但有时候肉眼看不出 explain 结果如何指导优化,这时候还需要有一些其他基础知识的佐助, ...
- Mysql子查询IN中使用LIMIT
学习下Mysql子查询IN中使用LIMIT的方法. 这两天项目里出了一个问题,mysql LIMIT使用后报错. 需求是这样的,我有3张表,infor信息表,mconfig物料配置表,maaply物料 ...
- MySQL 子查询 EXISTS 和 NOT EXISTS(转)
MySQL EXISTS 和 NOT EXISTS 子查询 MySQL EXISTS 和 NOT EXISTS 子查询语法如下: SELECT ... FROM table WHERE EXISTS ...
- mysql子查询慢的问题
当你在用explain工具查看sql语句的运行计划时.若select_type 字段中出现"DEPENDENT SUBQUERY"时,你要注意了.你已经掉入了mysql子查询慢 ...
- MySQL子查询慢现象的解决
当你在用explain工具查看sql语句的执行计划时,若select_type 字段中出现“DEPENDENT SUBQUERY”时,你要注意了,你已经掉入了mysql子查询慢的“坑". 相 ...
- MySQL子查询有哪五种形式?
MySQL是一个关系型数据库管理系统,由瑞典MySQLAB公司开发,目前属于Oracle旗下产品.MySQL是最流行的关系型数据库管理系统之一,在web应用方面,MySQL是最好的RDBMS(Rela ...
随机推荐
- python3.6+pycharm+robotframework 环境搭建
参考文档:https://www.cnblogs.com/chenyuebai/p/8359577.html, https://www.cnblogs.com/jiyanjiao-702521/p/9 ...
- android studio: 9:57 Unsupported Modules Detected: Compilation is not supported for following modules: map, app, ota, MediaEditor, rcLcmSercive, DroneSDK, qrcodelibrary, rcService, speechService. Unfo
Android studio Error “Unsupported Modules Detected: Compilation is not supported for following modul ...
- PorterDuffXfermode之PorterDuff.Mode.LIGHTEN
package com.loaderman.customviewdemo.view; import android.content.Context; import android.graphics.B ...
- ISO/IEC 9899:2011 条款6.2.5——类型
6.2.5 类型 1.存储在一个对象中的值或由一个函数所返回的值的意义由用于访问该对象的表达式的类型来确定.(声明为一个对象的一个标识符是最简单的这种表达式:其类型在标识符的声明中指定.)类型被划分为 ...
- Greenwich.SR2版本的Spring Cloud Ribbon实例
上次我们了解了eureka(参见Greenwich.SR2版本的Spring Cloud Eureka实例),里面的服务消费方(服务实例a-beautiful-client)我们其实已经用到了ribb ...
- java编写的一段简单的网络爬虫demo代码
功能: 从网站上下载附件,并从页面中提取页面文章内容 关于NIO 在大多数情况下,Java 应用程序并非真的受着 I/O 的束缚.操作系统并非不能快速传送数据,让 Java 有事可做:相反,是 JVM ...
- es6 fetch方法请求接口
fetch(url, { method: 'post', headers: { 'Content-type': 'application/x-www-form-urlencoded; charset= ...
- (转)华为 安卓手机在MAC系统下 ADB 识别
使用MACOS发现在Android开发环境完整的情况下,接入小米,SAMSUNG,HTC,ZTE等手机都可以自动识别,如果暂时不能识别,只需要在 adb_usb.ini 中设置之后也可以识别,并可以在 ...
- linux下的进程间通信之消息队列
概念: 进程彼此之间可以通过IPC消息进行通信.进程产生的每条消息都被发送到一个IPC消息队列中,这条消息一直存放在队列中,直到另一个进程将其读走为止. 优点:可以通过发送消息来几乎完全避免命名管道的 ...
- 纯小白安装MongoDB的图形界面工具adminMongo
今天安了两个MongoDB的图形界面工具,robot3和adminMongo,至于为什么安两个....因为网上说啥好用的都有,我也很迷... 安装adminMongo的时候...和正常软件安装流程不太 ...