【MySQL】子查询之一

MySQL 从版本4 开始支持 SQL 标准要求的所有子查询格式和操作,同时扩展了特有的几种特性。本文会介绍子查询的类型以及相关的注意点。

一 什么是子查询

    子查询是将一个 SELECT 语句的查询结果作为中间结果,供另一个 SQL 语句调用。如:

SELECT * FROM t1  WHERE vid in  (SELECT  vid FROM t2);

二 MySQL 子查询分类

      根据子查询的返回数据形式,mysql 子查询可以分为以下几类:

a  标量子查询

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

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

使用子查询进行比较

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

SELECT * FROM t1 WHERE vid = (SELECT MAX(col2) FROM t2);

b 列子查询

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

一个列子查询的例子如下:

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

c 行子查询

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

一个行子查询的例子如下:

SELECT * FROM table1 WHERE (1,2) = (SELECT vid, col2 FROM table2)

   在该例子中,在保证子查询返回单一行数据的前提下,如果 vid=1 且 col2=2 ,则该查询结果为 TRUE。

MySQL 行构造符 

    在上面的例子中,WHERE 后面的 (1,2) 被称为行构造符,也可以写为ROW(1,2)。行构造符通常用于与对能返回两个或两个以上列的子查询进行比较。

d FROM 子句中的子查询

   MySQL FROM 子查询是指 FROM 的子句作为子查询语句,主查询再到子查询结果中获取需要的数据。FROM 子查询语法如下:

SELECT ... FROM (subquery) AS name ...

子查询会生成一个临时表,由于 FROM 子句中的每个表必须有一个名称,因此 AS name 是必须的。FROM 子查询也称为衍生数据表子查询。

注意

MySQL FROM 子句中的子查询可以返回标量、列、行或表,但不能为有关联的子查询。

e 表子查询

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

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

该 SQL 的意义在于查找 article 表中指定的字段同时也存在于 blog 表中的所有的行(注意 = 比较操作符换成了 IN),实际上等同于下面的条件语句:
SELECT * FROM article,blog 
WHERE (article.title=blog.title AND article.content=blog.content AND article.uid=blog.uid)

实际上,很多 in 的子查询都可以修改为 join方式和关联查询,而且相比而言后面的效率更高。

f MySQL EXISTS 和 NOT EXISTS 子查询

其语法如下:

SELECT ... FROM table WHERE  EXISTS (subquery)

该语法可以理解为:

将主查询的数据,放到子查询中做条件验证,根据验证结果(TRUE 或 FALSE)来决定主查询的数据结果是否得以保留。

注意:

  1 EXISTS (subquery) 只返回 TRUE 或 FALSE,因此子查询中的 SELECT * 也可以是 SELECT 1 或其他,官方说法是实际执行时会忽略 SELECT 清单,因此没有区别。

  2 EXISTS 子查询的实际执行过程可能经过了优化而不是我们理解上的逐条对比,如果担忧效率问题,可进行实际检验以确定是否有效率问题。

  3 EXISTS 子查询往往也可以用条件表达式、其他子查询或者 JOIN 来替代,何种最优需要具体问题具体分析。

g MySQL 关联子查询

        关联子查询通俗一点来讲,就是子查询引用到了主查询的数据数据。

以一个实际的例子来理解关联子查询:

SELECT * FROM article WHERE uid IN (SELECT uid FROM user WHERE article.uid = user.uid);

但在关联子查询中,是无法单独执行子查询语句的。其实际流程大致为:

    1 先做外部主查询;

    2 将主查询的值传入子查询并执行;

    3 子查询再将查询结果返回主查询,主查询根据返回结果完成最终的查询。

 这个执行流程类似于 EXISTS 子查询,实际上某些情况下 MySQL 就是将关联子查询重写为 EXISTS 子查询来执行的。


三  小结

      上文简单介绍了子查询的常见用法,但是生产环境中仅仅知道用法还是不够的,mysql 本身的子查询机制(将在下文介绍)使得dba在生产环境中使用子查询是必须谨慎。

时间: 2024-11-01 04:53:07

【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

sql性能优化-mysql子查询是否被重复执行?

问题描述 mysql子查询是否被重复执行? 请教!mysql返回固定结果集时,是否被重复执行 例如1:select t.*,(select count(1) from table01) from table01 t; 例如2:select t.*,(select count(1) from table01 t2 where t2.key=t1.key) from table01 t1 ;--像这种嵌套的子查询是会被重复执行的. 疑问:上面例子1中的子查询遍历过程中,都是固定结果集,会被重复执行N

MySQL子查询用法实例分析_Mysql

本文实例讲述了MySQL子查询用法.分享给大家供大家参考,具体如下: 假设表my_tbl包含三个字段a,b,c:现在需要查询表中列a的每个不同值下的列b为最小值的记录量. 比如表记录为: a  b  c 1  3  'cd' 2  3  'nhd' 1  5  'bg' 2  6  'cds' 1  7  'kiy' 3  7  'vsd' 3  8  'ndf' 希望得到结果为: a  b  c 1  3  'cd' 2  3  'nhd' 3  7  'vsd' (1) 其中一个做法:先查出

MySQL子查询的几种常见形式介绍_Mysql

mysql子查询的几种常见写法: 复制代码 代码如下: select * from xxx where col = [any|all](select * from xxxx);   该句法可分为加关键词和不加关键词的写法,当不加关键词的时候,子查询语句返回的是一个离散值(注意是一个),查询语句将以子查询语句的结果作为自己 where子句的条件进行查询,该句法可以在子查询语句前加入any.all.some等关键字,此时子查询语句返回的是一组离散值.any则表示,查询语句是以子查询返回的值作为一个范

mysql子查询where/having/in/exists/from例子

where/having查询 MySQL可以在where子句或者having子句中包含子查询.包含在圆括号内的子查询,优先级高于比较和逻辑操作符.in操作符或者 exists操作符. 也可以在一个having子句中的比较运算符前使用子查询,从而用它对父查询创建的组进行过滤. where和having的区别 HAVING是先分组再筛选记录,WHERE在聚合前先筛选记录.也就是说作用在GROUP BY 子句和HAVING子句前:而 HAVING子句在聚合后对组记录进行筛选. 作用的对象不同.WHER

对MySQL子查询的简单改写优化_Mysql

使用过oracle或者其他关系数据库的DBA或者开发人员都有这样的经验,在子查询上都认为数据库已经做过优化,能够很好的选择驱动表执行,然后在把该经验移植到mysql数据库上,但是不幸的是,mysql在子查询的处理上有可能会让你大失所望,在我们的生产系统上就由于碰到了这个问题: select i_id, sum(i_sell) as i_sell from table_data where i_id in (select i_id from table_data where Gmt_create

MYSQL子查询与连接

37:子查询与连接SET 列名 gbk;//改变客户端数据表的编码类型. 子查询子查询(Subquery)是指出现在其他SQL语句内的SELECT子句例如SELECT * FROM t1 WHERE col1=(SELECT col2 FROM t2);其中SELECT * FROM t1称为Outer Query/Outer StatementSELECT col2 FROM FROM t2,称为SubQuery 子查询指嵌套在查询内部,且必须始终出现在圆括号内.子查询可以包含多个关键字或者条

Mysql子查询和联合(UNION)查询详解

查询:  在select查询中,又嵌套了一个select查询.一个是外层查询,另一个是内层查询. Where子查询 就是在where查询语句有一个select语句,把内层查询的结果当做外层查询的条件. From子查询 在from 查询语句中,有一个select语句,把内层查询结果作为一张临时表,供外层再一次查询. 区别: 对于不是唯一取值的列,使用where子查可能会出现不正确的结果.如果用from,有分组的情况下,我们要通过排序把需要的记录放在第一的位置上. Exists #查询有商品的栏目

Mysql子查询

问题描述 有谁可以解释一下这段查询的意思? SELECT * FROM table1 t1  WHERE 1=1  and t1_id in (select table1_id from table2 t2 where 1=1  and (t2.t2_name like '%wangwu%'  or  t1.t1_name like '%zhansan%') ); table1  +---------------------+| t1_id |   t1_name   |+-----------

mySQL子查询拿不出数据

问题描述 我的mySQL是5.0版本的可是select * from rights where id not in ( select id from rights limit 80) limit 10;这句还是说不支持这是为什么呢? 解决方案 首先 你的版本可能太低了不支持这个子查询:当然我的也不支持 所以出错引用This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'如果你的 意思是分页 或者查询第