Mysql——子查询

子查询的位置:

select 中、from 后、where 中.group by 和order by 中无实用意义。

子查询分为如下几类:

1,标量子查询:返回单一值的标量,最简单的形式。

2,列子查询:返回的结果集是 N 行一列。

3,行子查询:返回的结果集是一行 N 列。

4,表子查询:返回的结果集是 N 行 N 列。

可以使用的操作符:= > < >= <= <> ANY IN SOME ALL EXISTS

标量子查询:是指子查询返回的是单一值的标量,如一个数字或一个字符串,也是子查询中最简单的返回形式。

可以使用 = > < >= <= <> 这些操作符对子查询的标量结果进行比较,通常子查询的位置在比较式的右侧

示例:

SELECT * FROM article WHERE uid = (SELECT uid FROM user WHERE status=1 ORDER BY uid DESC LIMIT 1)

SELECT * FROM t1 WHERE column1 = (SELECT MAX(column2) FROM t2)

SELECT * FROM article AS t WHERE 2 = (SELECT COUNT(*) FROM article WHERE article.uid = t.uid)

MySQL 列子查询:指子查询返回的结果集是 N 行一列,该结果通常来自对表的某个字段查询返回。

可以使用 = > < >= <= <> 这些操作符对子查询的标量结果进行比较,通常子查询的位置在比较式的右侧

示例:可以使用 IN、ANY、SOME 和 ALL 操作符,不能直接使用 = > < >= <= <> 这些比较标量结果的操作符。

示例:

SELECT * FROM article WHERE uid IN(SELECT uid FROM user WHERE status=1)

SELECT s1 FROM table1 WHERE s1 > ANY (SELECT s2 FROM table2)

SELECT s1 FROM table1 WHERE s1 > ALL (SELECT s2 FROM table2)

NOT IN 是 <> ALL 的别名,二者相同。

特殊情况

如果 table2 为空表,则 ALL 后的结果为 TRUE;

如果子查询返回如 (0,NULL,1) 这种尽管 s1 比返回结果都大,但有空行的结果,则 ALL 后的结果为 UNKNOWN 。

注意:对于 table2 空表的情况,下面的语句均返回 NULL:

SELECT s1 FROM table1 WHERE s1 > (SELECT s2 FROM table2)

SELECT s1 FROM table1 WHERE s1 > ALL (SELECT MAX(s1) FROM table2)

MySQL 行子查询:指子查询返回的结果集是一行 N 列,该子查询的结果通常是对表的某行数据进行查询而返回的结果集。

例子:

SELECT * FROM table1 WHERE (1,2) = (SELECT column1, column2 FROM table2)

注:(1,2) 等同于 row(1,2)

SELECT * FROM article WHERE (title,content,uid) = (SELECT title,content,uid FROM blog WHERE bid=2)

MySQL 表子查询:指子查询返回的结果集是 N 行 N 列的一个表数据。

例子:

SELECT * FROM article WHERE (title,content,uid) IN (SELECT title,content,uid FROM blog)

子查询优化:

很多查询中需要使用子查询。使用子查询可以一次性的完成很多逻辑上需要多个步骤才能完成的SQL操作,同时也可以避免事务或者表锁死。子查询可以使查询语句很灵活,但子查询的执行效率不高。子查询时,MySQL需要为内层查询语句的查询结果建立一个临时表。然后外层查询语句再临时表中查询记录。查询完毕后,MySQL需要撤销这些临时表。因此,子查询的速度会受到一定的影响。如果查询的数据量比较大,这种影响就会随之增大。在MySQL中可以使用连接查询来替代子查询。连接查询不需要建立临时表,其速度比子查询要快。

使用连接(JOIN)来代替子查询

如:

例子1:

SELECT * FROM t1

WHERE t1.a1 NOT in (SELECT a2 FROM t2 )

优化后:

SELECT * FROM t1

LEFT JOIN t2 ON t1.a1=t2.a2

WHERE t2.a2 IS NULL

例子2:

SELECT * FROM article WHERE (title,content,uid) IN (SELECT title,content,uid FROM blog)

优化后:

SELECT * FROM article

inner join blog

on (article.title=blog.title AND article.content=blog.content AND article.uid=blog.uid)

不能优化的子查询:

1、mysql不支持子查询合并和聚合函数子查询优化,mariadb对聚合函数子查询进行物化优化;

2、mysql不支持from子句子查询优化,mariadb对from子句子查询进行子查询上拉优化;

3、mysql和mariadb对子查询展开提供有限的支持,如对主键的操作才能进行上拉子查询优化;

4、mysql不支持exists子查询优化,mariadb对exists关联子查询进行半连接优化,对exists非关联子查询没有进一步进行优化;

5、mysql和mariadb不支持not exists子查询优化;

6、mysql和mariadb对in子查询,对满足半连接语义的查询进行半连接优化,再基于代价评估进行优化,两者对半连接的代价评估选择方式有差异;

7、mysql不支持not in子查询优化,mariadb对非关联not in子查询使用物化优化,对关联not in子查询不做优化;

8、mysql和mariadb对>all非关联子查询使用max函数,<all非关联子查询使用min函数,对=all和非关联子查询使用exists优化;

9、对>some和>any非关联子查询使用min函数,对<some和<any非关联子查询使用max函数,=any和=some子查询使用半连接进行优化,对>some和>any关联子查询以及<some和<any关联子查询只有exists优化。

Mysql——子查询,布布扣,bubuko.com

时间: 2024-12-24 11:18:26

Mysql——子查询的相关文章

mysql子查询慢的问题

当你在用explain工具查看sql语句的执行计划时,若select_type 字段中出现"DEPENDENT SUBQUERY"时,你要注意了,你已经掉入了mysql子查询慢的"坑"...下面我们来看一个具体的例子 有这样一条查询语句: SELECT gid,COUNT(id) as count FROM shop_goods g1 WHERE status =0 and gid IN (SELECT gid FROM shop_goods g2 WHERE si

MySQL 子查询

-- 商品类别表 --CREATE TABLE category( cat_id INT PRIMARY KEY AUTO_INCREMENT,#类别编号 cat_name VARCHAR(30) NOT NULL#类别名称); -- 商品表 --CREATE TABLE goods( goods_id INT PRIMARY KEY AUTO_INCREMENT,#商品编号 goods_name VARCHAR(30) NOT NULL,#商品名称 goods_price DOUBLE,#商品

MySQL子查询

到目前为止我们所看到的SELECT语句都是简单查询,即从单个数据库表中检索数据的单条语句.SQL还允许创建子查询,即嵌套在其他查询语句中的查询. 下面给出嵌套查询的例子. 一个表示存储订单信息,包括订单号,客户ID,订单日期等,如下所示: 一张表示存储订单物品信息,如下: 还有一张表存储的是客户的信息,如下: 假如现在的需求是要找出订购物品TNT2的所有客户.我们发现通过第二张订购物品表能够获取到订单编号,依据订单编号,可以再第一张订单信息表中获取到相应的客户id,通过客户id即可以在第三张表中

MySQl 子查询,左右连接,多表连接学习笔记

1.子查询是指在另一个查询语句中的SELECT子句. 例句: SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2); 其中,SELECT * FROM t1 ...称为Outer Query[外查询](或者Outer Statement), SELECT column1 FROM t2 称为Sub Query[子查询]. 所以,我们说子查询是嵌套在外查询内部.而事实上它有可能在子查询内部再嵌套子查询. 子查询必须出现在圆括号之间. 行

MySQL子查询的优化

一.MySQL子查询的位置 当一个查询是另一个查询的子部分是,称之为子查询(查询语句中嵌套含有查询语句).子查询也是使用频率比较高的一种查询类型.因此,优化子查询,对于整个系统的性能也有直接的影响. 从查询出现在SQL语句的位置来看,它可以出现在目标列中,也可以出现在from子句中,还可以出现在JOIN/ON子句.GROUPBY子句.HAVING子句.ORDERBY子句等位置.下面依次来看这几种形式的子查询,以及对他们进行优化的一些想法. 1.子查询出现在目标列位置 当子查询出现在目标列位置的时

MySQL子查询有哪五种形式?

MySQL是一个关系型数据库管理系统,由瑞典MySQLAB公司开发,目前属于Oracle旗下产品.MySQL是最流行的关系型数据库管理系统之一,在web应用方面,MySQL是最好的RDBMS(RelationalDatabaseManagementSystem,关系数据库管理系统)应用软件. mysql从4.1版开始支持子查询功能,在此版本前,可以用join写连表查询来进行替代,但不推荐这么写,相当的麻烦.以下是mysql子查询的几种常见写法: 1.select*fromxxxwherecol=

MySQL子查询慢现象的解决

当你在用explain工具查看sql语句的执行计划时,若select_type 字段中出现“DEPENDENT SUBQUERY”时,你要注意了,你已经掉入了mysql子查询慢的“坑". 相关书籍:高性能MySQL(第3版) 中文PDF带目录清晰版 http://www.linuxidc.com/Linux/2014-10/108464.htm 下面我们来看一个具体的例子 有这样一条查询语句: SELECT gid,COUNT(id) as count FROM shop_goods g1 WH

MySQL 子查询用法和注意事项

有时候一条sql语句解决不了什么问题,需要嵌套sql语句来实现目标,但是会影响执行的效率,这里简单说说其用法和注意事项. MySQL子查询是嵌套在另一个查询(如SELECT,INSERT,UPDATE或DELETE)中的查询. 1,MySQL子查询在WHERE子句中 =,>,< WHERE子句中使用IN或NOT IN运算符 SELECT customerNumber, checkNumber, amountFROMpaymentsWHEREamount > (SELECT AVG(amo

【mysql】 mysql 子查询、联合查询、模糊查询、排序、聚合函数、分组----------语法

第二章 mysql 一.模糊查询 like 1. 字段 like '河北省%' %代表任何N个字符 2 字段 like '河北省____' _代表任意1个字符 二.IN 语法:SELECT 字段列1,字段2 ,…FROM 表名 WHERE 字段x IN ( 值1,值2,值3…) 三.排序 语法:select 字段1, 字段2, ... from 表名 where 条件 order by 字段 [asc|desc] asc :升序 desc :降序 默认是升序asc SELECT * FROM s