MySQL数据库子查询 sub query

目录
  • 1、基本概念
    • 1.1、子查询
    • 1.2、主查询
    • 1.3、子查询和主查询的关系
    • 1.4、子查询的分类
  • 2、标量子查询
    • 2.1、基本语法
    • 2.2、示例
  • 3、列子查询
    • 3.1、基本语法
    • 3.2、示例
  • 4、行子查询
    • 4.1、基本语法
    • 4.2、示例
  • 5、表子查询
    • 5.1、基本语法
    • 5.2、示例
  • 6、exists子查询
    • 6.1、基本语法
    • 6.2、示例
  • 7、子查询中的特定关键字
    • 7.1、in
    • 7.2、any
    • 7.3、some
    • 7.4、all
    • 7.5、值为null

1、基本概念

1.1、子查询

嵌套查询下层的程序模块,当一个查询是另一个查询的条件时,称之为子查询

一条select语句中,嵌入了另一条select语句

1.2、主查询

主要的查询对象,第一条select语句,确定所获取的数据目标(数据源)

1.3、子查询和主查询的关系

  • 子查询是嵌入到主查询中的
  • 子查询辅助主查询,要么作为条件,要么作为数据源
  • 子查询可以独立存在,是一条完整的select语句

1.4、子查询的分类

1、按功能分

  • 标量子查询:子查询返回的结果是一个数据(一行一列)
  • 列子查询:返回一列(一列多行)
  • 行子查询:返回一行(一行多列)
  • 表子查询:返回多行多列
  • exists子查询 返回1或者0(类似布尔操作)

2、按位置分

  • where子查询
  • from子查询

2、标量子查询

查询结果是一个数据(一行一列)

2.1、基本语法

-- 子查询得到的结果只有一个值
select * from 数据源 where 条件判断 =/<> (select 字段名 form 数据源 where 条件判断);

2.2、示例

-- 知道学生的id,查询所在班级名字
-- 主查询:班级,子查询:班级id

mysql> select * from my_student;
+----+--------+----------+------+--------+
| id | name   | class_id | age  | gender |
+----+--------+----------+------+--------+
|  1 | 刘备   |        1 |   18 |      2 |
|  2 | 李四   |        1 |   19 |      1 |
|  3 | 王五   |        2 |   20 |      2 |
|  4 | 张飞   |        2 |   21 |      1 |
|  5 | 关羽   |        1 |   22 |      2 |
|  6 | 曹操   |        1 |   20 |   NULL |
+----+--------+----------+------+--------+

mysql> select * from my_class;
+----+--------+
| id | name   |
+----+--------+
|  1 | 一班   |
|  3 | 三班   |
|  2 | 二班   |
+----+--------+

select class_id from my_student where id = 1;
+----------+
| class_id |
+----------+
|        1 |
+----------+

select * from my_class where id = (
    select class_id from my_student where id = 1
);
+----+--------+
| id | name   |
+----+--------+
|  1 | 一班   |
+----+--------+

3、列子查询

列子查询得到的结果是一列数据,一列多行

3.1、基本语法

主查询 where 条件 in (列子查询)

3.2、示例

-- 获取有学生的班级名字
-- 1、找到学生表中的所有班级id
-- 2、找出班级表中对应的名字

select distinct(class_id) from my_student;
+----------+
| class_id |
+----------+
|        1 |
|        2 |
+----------+

select name from my_class where id in (
    select distinct(class_id) from my_student
);
+--------+
| name   |
+--------+
| 一班   |
| 二班   |
+--------+

4、行子查询

行子查询返回的结果是一行多列

  • 字段元素:一个字段对应的值
  • 行元素:多个字段合起来作为一个元素参与运算

4.1、基本语法

主查询 where 条件 [(构造一个行元素)] = (行子查询);

4.2、示例

获取班级年龄最大,且班级号最大的学生

  • 1、求年龄最大
  • 2、求班级号最大
  • 3、求出学生
-- 错误示例
select * from my_student having age = max(age) and class_id = max(class_id);
-- 1、having在group by之后,代表group by执行了一次,聚合函数使用
-- 2、group by 一旦执行,结果就是只返回一行记录,第一行 

select max(age), max(class_id) from my_student;
+----------+---------------+
| max(age) | max(class_id) |
+----------+---------------+
|       22 |             2 |
+----------+---------------+

select * from my_student where (age, class_id) = (
    select max(age), max(class_id) from my_student
);
Empty set (0.01 sec)

select * from my_student where (age, class_id) = (
    select max(age), min(class_id) from my_student
);
+----+--------+----------+------+--------+
| id | name   | class_id | age  | gender |
+----+--------+----------+------+--------+
|  5 | 关羽   |        1 |   22 |      2 |
+----+--------+----------+------+--------+

总结:

标量子查询、列子查询、行子查询都属于where子查询

5、表子查询

表子查询返回结果是多行多列,与行子查询相似

行子查询需要行元素,表子查询没有

  • 行子查询用于where条件判断,属于where子查询
  • 表子查询用于from数据源,属于from子查询

5.1、基本语法

select 字段表 from (表子查询) as 别名 [where] [group by] [having] [order by] [limit]

5.2、示例

获取每个班级年龄最大的学生:

-- 错误示例
select * from my_student group by class_id having age = max(age);
将每个班年龄最大的学生排在最前面 order by
针对结果进行group by 保留每组第一条数据
--
select * from (
    select * from my_student order by age desc
) as t group by t.class_id;
+----+--------+----------+------+--------+
| id | name   | class_id | age  | gender |
+----+--------+----------+------+--------+
|  1 | 刘备   |        1 |   18 |      2 |
|  3 | 王五   |        2 |   20 |      2 |
+----+--------+----------+------+--------+

6、exists子查询

返回结果只有0或者1,1代表成立,0代表不成立

6.1、基本语法

where exists (查询语句)
-- 永远为真
where 1;

6.2、示例

-- 查询有学生的所有班级
select * from my_class as c where exists (
    select id from my_student as s where s.class_id = c.id
);
+----+--------+
| id | name   |
+----+--------+
|  1 | 一班   |
|  2 | 二班   |
+----+--------+

7、子查询中的特定关键字

mysql> select * from my_student;
+----+--------+----------+------+--------+
| id | name   | class_id | age  | gender |
+----+--------+----------+------+--------+
|  1 | 刘备   |        1 |   18 |      2 |
|  2 | 李四   |        1 |   19 |      1 |
|  3 | 王五   |        2 |   20 |      2 |
|  4 | 张飞   |        2 |   21 |      1 |
|  5 | 关羽   |        1 |   22 |      2 |
|  6 | 曹操   |        1 |   20 |   NULL |
+----+--------+----------+------+--------+

mysql> select id from my_class;
+----+
| id |
+----+
|  1 |
|  3 |
|  2 |
+----+

7.1、in

主查询 where 条件 in (列子查询)

select * from my_student where class_id in (select id from my_class);
+----+--------+----------+------+--------+
| id | name   | class_id | age  | gender |
+----+--------+----------+------+--------+
|  1 | 刘备   |        1 |   18 |      2 |
|  2 | 李四   |        1 |   19 |      1 |
|  3 | 王五   |        2 |   20 |      2 |
|  4 | 张飞   |        2 |   21 |      1 |
|  5 | 关羽   |        1 |   22 |      2 |
|  6 | 曹操   |        1 |   20 |   NULL |
+----+--------+----------+------+--------+

7.2、any

-- 查询结果中有任意一个匹配即可,等价于in
主查询 where 条件 any (列子查询)

select * from my_student where class_id = any (select id from my_class);
+----+--------+----------+------+--------+
| id | name   | class_id | age  | gender |
+----+--------+----------+------+--------+
|  1 | 刘备   |        1 |   18 |      2 |
|  2 | 李四   |        1 |   19 |      1 |
|  3 | 王五   |        2 |   20 |      2 |
|  4 | 张飞   |        2 |   21 |      1 |
|  5 | 关羽   |        1 |   22 |      2 |
|  6 | 曹操   |        1 |   20 |   NULL |
+----+--------+----------+------+--------+

-- 不等于任意一个
主查询 where 条件 any <> (列子查询)
select * from my_student where class_id <> any (select id from my_class);
+----+--------+----------+------+--------+
| id | name   | class_id | age  | gender |
+----+--------+----------+------+--------+
|  1 | 刘备   |        1 |   18 |      2 |
|  2 | 李四   |        1 |   19 |      1 |
|  3 | 王五   |        2 |   20 |      2 |
|  4 | 张飞   |        2 |   21 |      1 |
|  5 | 关羽   |        1 |   22 |      2 |
|  6 | 曹操   |        1 |   20 |   NULL |
+----+--------+----------+------+--------+

7.3、some

与any完全一样

7.4、all

-- 等于其中所有
=all(列子查询)
select * from my_student where class_id = all (select id from my_class);
Empty set (0.00 sec)
select * from my_class where id = all (select class_id from my_student);
Empty set (0.00 sec)
-- 不等于其中所有
<>all(列子查询)
select * from my_student where class_id <> all (select id from my_class);
Empty set (0.00 sec)
select * from my_class where id <> all (select class_id from my_student);
+----+--------+
| id | name   |
+----+--------+
|  3 | 三班   |
+----+--------+

7.5、值为null

如果值为null,不参与匹配

mysql> select * from my_student;
+----+--------+----------+------+--------+
| id | name   | class_id | age  | gender |
+----+--------+----------+------+--------+
|  1 | 刘备   |        1 |   18 |      2 |
|  2 | 李四   |        1 |   19 |      1 |
|  3 | 王五   |        2 |   20 |      2 |
|  4 | 张飞   |        2 |   21 |      1 |
|  5 | 关羽   |     NULL |   22 |      2 |
|  6 | 曹操   |        1 |   20 |   NULL |
+----+--------+----------+------+--------+

mysql> select * from my_student where class_id = any (select id from my_class);
+----+--------+----------+------+--------+
| id | name   | class_id | age  | gender |
+----+--------+----------+------+--------+
|  1 | 刘备   |        1 |   18 |      2 |
|  2 | 李四   |        1 |   19 |      1 |
|  3 | 王五   |        2 |   20 |      2 |
|  4 | 张飞   |        2 |   21 |      1 |
|  6 | 曹操   |        1 |   20 |   NULL |
+----+--------+----------+------+--------+

mysql> select * from my_student where class_id <> any (select id from my_class);
+----+--------+----------+------+--------+
| id | name   | class_id | age  | gender |
+----+--------+----------+------+--------+
|  1 | 刘备   |        1 |   18 |      2 |
|  2 | 李四   |        1 |   19 |      1 |
|  3 | 王五   |        2 |   20 |      2 |
|  4 | 张飞   |        2 |   21 |      1 |
|  6 | 曹操   |        1 |   20 |   NULL |
+----+--------+----------+------+--------+

到此这篇关于MySQL数据库子查询 sub query的文章就介绍到这了,更多相关MySQL sub query内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 浅谈为什么MySQL不推荐使用子查询和join

    做分页查询: 1.对于mysql,不推荐使用子查询和join是因为本身join的效率就是硬伤,一旦数据量很大效率就很难保证,强烈推荐分别根据索引单表取数据,然后在程序里面做join,merge数据. 2.子查询就更别用了,效率太差,执行子查询时,MYSQL需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响,这里多了一个创建和销毁临时表的过程. 3.如果是JOIN的话,它是走嵌套查询的.小表驱动大表,且通过索引字段进行关联.如果表记录比较少的话,还是OK的.大的话业务逻

  • MySQL 子查询和分组查询

    概述 子查询是SQL查询中的重要一块,是我们基于多表之间进行数据聚合和判断的一种手段,使得我们的处理复杂数据更加的便捷,这一节我们主要来了解一下子查询. 先做一下数据准备,这边建立三张表:班级.学生.毕业成绩表,用于后面的操作: drop database if exists `Helenlyn_Class`; create database `Helenlyn_Class`; /*班级表*/ DROP TABLE IF EXISTS `classes`; CREATE TABLE `class

  • MySQL嵌套查询实现子查询的方法

    目录 一个查询语句嵌套在另一个查询语句内部的查询 1.带ANY(SOME)关键字的子查询 2.带ALL关键字的子查询 3.带EXISTS关键字的子查询 4.带IN关键字的子查询 5.带比较运算符的子查询 一个查询语句嵌套在另一个查询语句内部的查询 常用操作符:ANY(SOME), ALL, IN, EXISTS 比较运算符:>, >=, <, <=, != 等 创建两个表,表明分别是tb1,tb2,并向其各插入了数据. 1.带ANY(SOME)关键字的子查询 这里any和some是

  • mysql连接查询、联合查询、子查询原理与用法实例详解

    本文实例讲述了mysql连接查询.联合查询.子查询原理与用法.分享给大家供大家参考,具体如下: 本文内容: 连接查询 联合查询 子查询 from子查询 where子查询 exists子查询 首发日期:2018-04-11 连接查询: 连接查询就是将多个表联合起来查询,连接查询方式有内连接.外连接.自然连接.交叉连接.连接查询使得可以同时查看多张表中数据. 内连接:有条件连接,多个表之间依据指定条件连接,匹配结果是保留符合匹配结果的记录. 外连接:与内连接不同的是不管匹配符不符合都保留,根据外连接

  • MySql子查询IN的执行和优化的实现

    目录 IN为什么慢? IN和EXISTS哪个快? 如何提高效率? MySQL5.6对子查询的优化? SEMI JOIN策略 Duplicate Weedout优化 Materialization优化 FirstMacth优化 LooseScan优化 SEMI JOIN变量 参考 IN为什么慢? 在应用程序中使用子查询后,SQL语句的查询性能变得非常糟糕.例如: SELECT driver_id FROM driver where driver_id in (SELECT driver_id FR

  • MySQL里面的子查询的基本使用

    目录 一.子查询定义 二.子查询分类 1. 标量子查询: 2. MySQL 列子查询: 3. MySQL 行子查询: 4. MySQL 表子查询: 三.字查询例举 1. ANY进行子查询 2. 使用IN进行子查询 3. 使用SOME进行子查询 4. 使用ALL进行子查询 5.标量子查询 6. 多值子查询 7. 独立子查询 8.相关子查询 9.EXISTS谓词 10. 派生表 四.子查询优化 一.子查询定义 定义: 子查询允许把一个查询嵌套在另一个查询当中. 子查询,又叫内部查询,相对于内部查询,

  • MySQL子查询中order by不生效问题的解决方法

    一个偶然的机会,发现一条SQL语句在不同的MySQL实例上执行得到了不同的结果. 问题描述 创建商品表product_tbl和商品操作记录表product_operation_tbl两个表,来模拟下业务场景,结构和数据如下: 接下来需要查询所有商品最新的修改时间,使用如下语句: select t1.id, t1.name, t2.product_id, t2.created_at from product_tbl t1 left join (select * from product_opera

  • MySQL数据库子查询 sub query

    目录 1.基本概念 1.1.子查询 1.2.主查询 1.3.子查询和主查询的关系 1.4.子查询的分类 2.标量子查询 2.1.基本语法 2.2.示例 3.列子查询 3.1.基本语法 3.2.示例 4.行子查询 4.1.基本语法 4.2.示例 5.表子查询 5.1.基本语法 5.2.示例 6.exists子查询 6.1.基本语法 6.2.示例 7.子查询中的特定关键字 7.1.in 7.2.any 7.3.some 7.4.all 7.5.值为null 1.基本概念 1.1.子查询 嵌套查询下层

  • MySQL数据库子查询语法规则详解

    目录 子查询简介 WHERE 子查询 FROM 子查询 SELECT 子查询 子查询是在查询语句里面再嵌套一个查询,这是因为我们在提取数据的时候有很多不知道的数据产生了依赖关系.此时我们就需要先查询一组数据的结果集,然后将这个结果集作用为下一个查询的对象.在 “表连接的章节”,我们曾说过子查询的效率低下的问题,其实并不是所有的子查询效率都是低下的,“WHERE” 子查询在匹配记录的时候要反复执行,这是不推荐使用的:但是如果将查询结果集当做一张表来使用,与其他的表做一个连接,这就是 “FROM”

  • 浅谈mysql的子查询联合与in的效率

    最近的产品测试发现一个问题,当并发数量小于10时,响应时间可以维持在100毫秒以内.但是当并发数到达30个时,响应时间就超过1秒.这太不能接受了,要求是通过1秒中并发100个. 经过检测发现,时间主要是耗在其中的一个存储过程中.把存储过程的语句一条一条的过一遍也没有发现明显的不合理.因为mysql本身不能提供毫秒级别的时间,google了一个mysql的能提供毫秒的时间函数,再做测试,做了一个定位.发现是其中一条语句,语句是这个样子: select .... from A, B where ..

  • mysql关联子查询的一种优化方法分析

    本文实例讲述了mysql关联子查询的一种优化方法.分享给大家供大家参考,具体如下: 很多时候,在mysql上实现的子查询的性能较差,这听起来实在有点难过.特别有时候,用到IN()子查询语句时,对于上了某种数量级的表来说,耗时多的难以估计.本人mysql知识所涉不深,只能慢慢摸透个中玄机了. 假设有这样的一个exists查询语句: select * from table1 where exists (select * from table2 where id>=30000 and table1.u

  • tp5.1框架数据库子查询操作实例分析

    本文实例讲述了tp5.1框架数据库子查询操作.分享给大家供大家参考,具体如下: 首先构造子查询SQL,可以使用下面三种的方式来构建子查询. 使用fetchSql方法 fetchSql方法表示不进行查询而只是返回构建的SQL语句,并且不仅仅支持select,而是支持所有的CURD查询. $subQuery = Db::table('think_user') ->field('id,name') ->where('id', '>', 10) ->fetchSql(true) ->

  • MySQL数据库高级查询和多表查询

    MySQL多表查询 添加练习表 -- 用户表(user) CREATE TABLE `user`( `id` INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户id(主键)', `username` VARCHAR(50) COMMENT '用户姓名', `age` CHAR(3) COMMENT '用户年龄' ); -- 订单表(orders) CREATE TABLE `orders`( `id` INT AUTO_INCREMENT PRIMARY KEY

  • MySQL的子查询中FROM和EXISTS子句的使用教程

    FROM 子查询 FROM 子句中的子查询 MySQL FROM 子查询是指 FROM 的子句作为子查询语句,主查询再到子查询结果中获取需要的数据.FROM 子查询语法如下: SELECT ... FROM (subquery) AS name ... 子查询会生成一个临时表,由于 FROM 子句中的每个表必须有一个名称,因此 AS name 是必须的.FROM 子查询也称为衍生数据表子查询. FROM 子查询实例 table1: s1 s2 1 5 2 12 3 20 FROM 子查询 SQL

  • MySQL中表子查询与关联子查询的基础学习教程

    MySQL 表子查询 表子查询是指子查询返回的结果集是 N 行 N 列的一个表数据. MySQL 表子查询实例 下面是用于例子的两张原始数据表: article 表: blog 表: SQL 如下: SELECT * FROM article WHERE (title,content,uid) IN (SELECT title,content,uid FROM blog) 查询返回结果如下所示: 该 SQL 的意义在于查找 article 表中指定的字段同时也存在于 blog 表中的所有的行(注

  • java实现连接mysql数据库单元测试查询数据的实例代码

    1.按照javaweb项目的要求逐步建立搭建起机构,具体的类包有:model .db.dao.test; 具体的架构详见下图: 2.根据搭建的项目架构新建数据库test和数据库表t_userinfo并且添加对应的测试数据; (这里我使用的是绿色版的数据库,具体的下载地址:http://pan.baidu.com/s/1mg88YAc) 具体的建立数据库操作详见下图: 3.编写包中的各种类代码,具体参考代码如下: UserInfo.java /** * FileName: UserInfo.jav

  • MySQL数据库SELECT查询表达式解析

    数据的管理在很大一部分是在进行查找工作,而SELECT占据了很大的一部分 SELECT select_expr [,select_expr...] [ FROM table_reference WHERE [where_condition] [GROUP BY {col_name | position} [ASC| DESC],...] [HAVING where_condition] [ORDER BY {col_name | expr |position} [ASC| DESC],...]

随机推荐