MySQL中几种常见的嵌套查询详解

目录
  • 几种常见的嵌套查询——以学员成绩为例
  • 含ANY或ALL关键词的嵌套查询
  • 含IN关键词的嵌套查询
  • 含EXISTS关键词的嵌套查询
  • 【补充】关于IN和EXISTS两个关键词还有两个延伸关键词NOT IN和NOT EXISTS
  • 附:其他使用方法和注意
  • 总结

几种常见的嵌套查询——以学员成绩为例

嵌套查询,也称为子查询,是实际工作中经常用到的一种查询方式。子查询其实就是在已有的查询语句中的where后面再嵌套一层查询语句,也就是把内层查询结果当做外层查询参照的数据表来使用。

在工作中,经常会遇见4种子查询,即含有比较运算符(>、>=、<、<=、=、!=)、IN关键词、ANY/ALL关键词以及EXISTS关键词的嵌套查询。下面我们以学员考试成绩为例,来学习一下这四种子查询的应用。

# 创建学员信息表
CREATE TABLE stu_info
(
id INT AUTO_INCREMENT PRIMARY KEY,
iname VARCHAR(20),
gender CHAR(1),
department VARCHAR(10),
age TINYINT,
province VARCHAR(10),
email VARCHAR(50),
mobilephone CHAR(11)
);
# 向学员表中插入数据
INSERT INTO stu_info(iname,gender,department,age,province,email,mobilephone) VALUES
('张勇','男','数学系',23,'河南','sfddf123dd@163.com','13323564321'),
('王兵','男','数学系',25,'江苏','lss1993@163.com','17823774329'),
('刘伟','男','计算机系',21,'江苏','qawsed112@126.com','13834892240'),
('张峰','男','管理系',22,'上海','102945328@qq.com','13923654481'),
('董敏','女','生物系',22,'浙江','82378339@qq.com','13428439022'),
('徐晓红','女','计算机系',24,'浙江','xixiaohong@gmail.com','13720097528'),
('赵伊美','女','数学系',21,'江苏','zhaomeimei@163.com','13417723980'),
('王建国','男','管理系',24,'浙江','9213228402@qq.com','13768329901'),
('刘清','女','统计系',23,'安徽','lq1128@gmail.com','17823651180'),
('赵家和','男','计算机系',28,'山东','dcrzdbjh@163.com','13827811311');

# 创建学员成绩表
CREATE TABLE stu_score( id INT , Excel TINYINT, Tableau TINYINT, MySQL TINYINT );
# 向成绩表中插入数据
INSERT INTO stu_score VALUES
(1,87,72,88),
(3,90,66,72),
(2,90,70,86),
(4,88,82,76),
(8,92,67,80),
(10,88,82,89),
(5,79,66,60),
(7,91,78,90),
(6,82,79,88),
(9,85,70,85); 

# 1.查询年龄超过所有学员平均年龄的学员信息
SELECT * FROM stu_info
WHERE age >= avg(age);
#需要注意的是Where后面不能使用聚合函数
#应该修改成
SELECT AVG(age) FROM stu_info;
SELECT * FROM stu_info
WHERE age>=23.3
#二合一
# 1.查询年龄超过所有学员平均年龄的学员信息
SELECT * FROM stu_info
WHERE age >= (SELECT AVG(age) FROM stu_info);

# 2.查询年龄不低于所属系平均年龄的学员信息
SELECT * FROM stu_info AS s1
WHERE age>= ( SELECT avg(age) FROM stu_info AS s2
			  WHERE s1.department = s2.department);

使用含比较运算符的嵌套查询时,需要注意,比较运算符后面的子查询只能返回一个结果。

含ANY或ALL关键词的嵌套查询

对于含比较运算符的嵌套查询来说,嵌套部分的查询语句只能返回一个值。那如果子查询返回多个值,就需要用到ANY或者ALL关键词了。通常,ANY / ALL 关键词经常和比较运算符连用,下面是6种比较运算符与ANY / ALL 关键词的搭配结果:

# 1.查询非管理系中比管理系任意一个学员年龄小的学员信息
SELECT * FROM stu_info
WHERE age < ANY(SELECT DISTINCT age FROM stu_info WHERE department = '管理系')
			AND department != '管理系';

这里的查询逻辑是这样的:首先查询管理系中学生的年龄(去重),得到的结果是22和24;然后查询出非管理系中年龄比22或24年龄小的学生信息(也就是年龄小于24的非管理系学生信息)。

# 2.查询非管理系中比管理系所有学员年龄大的学员信息
SELECT * FROM stu_info
WHERE age > ALL (SELECT DISTINCT age FROM stu_info WHERE department = '管理系')
      AND department != '管理系';

这里的查询逻辑是这样的:首先查询管理系中学生的年龄(去重),得到的结果是22和24;然后查询出非管理系中年龄比22和24都大的学生信息(也就是年龄大于24的非管理系学生信息)。

含IN关键词的嵌套查询

当查询条件涉及某些已知的可枚举离散值的时候,我们就可以选择IN关键词来完成数据的提取。IN关键词有两种用法:

  1. 将可枚举的离散值直接写在值列表中
  2. 当离散值是基于其他表的筛选结果时,就可以使用嵌套查询,即把另一个表的查询语句块写在IN关键词后面的括号里。
# 1.查询数学系和计算机系的学员信息
SELECT * FROM stu_info WHERE department IN('数学系','计算机系');
# 2.查询与张勇、刘伟同一个系的学员信息
SELECT * FROM stu_info
WHERE department IN (SELECT department FROM stu_info WHERE iname IN('张勇','刘伟'));
# 3.查询MySQL成绩大于85分的学员信息
SELECT * FROM stu_info
WHERE id IN (SELECT id FROM stu_score WHERE MySQL > 85);

需要注意的是,在使用IN关键词的嵌套查询的时候,嵌套部分只能返回一个字段的信息(比如上面的department字段或者id字段),如果返回两个及以上字段信息则会出现语法错误。

含EXISTS关键词的嵌套查询

EXISTS 关键词的作用和 IN关键词非常类似,不同的是,通过EXISTS关键词的嵌套查询返回的不是具体的值集合,而是满足条件的逻辑值(也就是True / False)。也就是说,EXISTS的作用就是“判断是否存在满足某种条件的记录”,如果存在这样的记录就返回真(True),如果不存在这样的记录就返回假(False)。

# 查询MySQL成绩大于85分的学员信息
SELECT * FROM stu_info
WHERE EXISTS
(SELECT * FROM stu_score WHERE stu_score.id = stu_info.id AND MySQL > 85);

需要注意的是,使用EXISTS关键词的嵌套语句 WHERE与EXISTS关键词之间没有任何参数,这是因为EXISTS只需要一个参数,通常是在EXISTS右侧加一个子查询语句。此外,EXISTS后面的子查询中SELECT后面可以写表中任何一个字段或者星号或者一个常数,因为EXISTS后面的子查询只关心是否存在满足条件的记录。下面返回的结果都是一样:

【补充】关于IN和EXISTS两个关键词还有两个延伸关键词NOT IN和NOT EXISTS

# 查询数学系和计算机系之外的学员信息
# 方法一
SELECT * FROM stu_info
WHERE department NOT IN('数学系','计算机系');
#方法二
SELECT * FROM stu_info
WHERE NOT EXISTS(SELECT * FROM stu_score WHERE department IN('数学系','计算机系') and stu_score.id = stu_info.id);
# not exists的逻辑比较复杂,需要大家慢慢领会
# 主要看not exists括号中的sql语句是否有结果,无结果:才会继续执行where条件;有结果:视为 where条件不成立。
# 当子查询和主查询有关联条件时,相当于从主查询中去掉子查询的数据。

对于IN和EXISTS两个关键词,大多数情况下都可以相互替换,主要差别是使用效率问题,通常情况下采用EXISTS要比IN效率要高,但也要看实际情况具体使用:IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。

以上我们只是了解了where语句后面的子查询,除此之外,子查询还可以放在select语句、from语句、having语句后面。

附:其他使用方法和注意

除了上面这些还有很多很多,不过就不去细讲了,因为这些跟别的数据库差不多,只是为了给大家一个参考,提提就够了。

         SELECT (SELECT s1 FROM t2) FROM t1;
         SELECT (SELECT s2 FROM t1);

支持子查询的语法有:SELECT,INSERT,UPDATE,DELETE,SET和DO。

子查询可以使用任何普通查询中使用的关键词:如DINSTINCT,GROUP BY,LIMIT,ORDER BY,UNION,ALL,UNION ALL等。可以使用<,>, <=, >=, =, <>运算符进行比较,也可以使用ANY ,IN和SOME进行集合的匹配。

总结

到此这篇关于MySQL中几种常见的嵌套查询的文章就介绍到这了,更多相关MySQL嵌套查询内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

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

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

  • mysql嵌套查询和联表查询优化方法

    嵌套查询糟糕的优化在上面我提到过,不考虑特殊的情况,联表查询要比嵌套查询更有效.尽管两条查询表达的是同样的意思,尽管你的计划是告诉服务器要做什么,然后让它决定怎么做,但有时候你非得告诉它改怎么做.否则优化器可能会做傻事.我最近就碰到这样的情况.这几个表是三层分级关系:category, subcategory和item.有几千条记录在category表,几百条记录在subcategory表,以及几百万条在item表.你可以忽略category表了,我只是交代一下背景,以下查询语句都不涉及到它.这

  • MYSQL子查询和嵌套查询优化实例解析

    查询游戏历史成绩最高分前100 Sql代码 SELECT ps.* FROM cdb_playsgame ps WHERE ps.credits=(select MAX(credits) FROM cdb_playsgame ps1 where ps.uid=ps1.uid AND ps.gametag=ps1.gametag) AND ps.gametag='yeti3' GROUP BY ps.uid order by ps.credits desc LIMIT 100; Sql代码 SEL

  • MySQL嵌套查询实例详解

    本文实例分析了MySQL嵌套查询.分享给大家供大家参考,具体如下: MySQl从4.11版后已经完全支持嵌套查询了,那么下面举些简单的嵌套查询的例子吧(源程序来自MySQL User Manual): 1. SELECT语句的子查询 语法: 复制代码 代码如下: SELECT ... FROM (subquery) AS name ... 先创建一个表: CREATE TABLE t1 (s1 INT, s2 CHAR(5), s3 FLOAT); INSERT INTO t1 VALUES (

  • 详解MySQL子查询(嵌套查询)、联结表、组合查询

    一.子查询 MySQL 4.1版本及以上支持子查询 子查询:嵌套在其他查询中的查询. 子查询的作用: 1.进行过滤: 实例1:检索订购物品TNT2的所有客户的ID = + 一般,在WHERE子句中对于能嵌套的子查询的数目没有限制,不过在实际使用时由于性能的限制,不能嵌套太多的子查询. 注意:列必须匹配 --在WHERE子句中使用子查询(如这里所示),应该保证SELECT语句具有与WHERE子句中相同数目的列.通常,子查询将返回单个列并且与单个列匹配,但如果需要也可以使用多个列. 示例2:返回订购

  • MySQL中几种常见的嵌套查询详解

    目录 几种常见的嵌套查询——以学员成绩为例 含ANY或ALL关键词的嵌套查询 含IN关键词的嵌套查询 含EXISTS关键词的嵌套查询 [补充]关于IN和EXISTS两个关键词还有两个延伸关键词NOT IN和NOT EXISTS 附:其他使用方法和注意 总结 几种常见的嵌套查询——以学员成绩为例 嵌套查询,也称为子查询,是实际工作中经常用到的一种查询方式.子查询其实就是在已有的查询语句中的where后面再嵌套一层查询语句,也就是把内层查询结果当做外层查询参照的数据表来使用. 在工作中,经常会遇见4

  • MySQL中使用去重distinct方法的示例详解

    一 distinct 含义:distinct用来查询不重复记录的条数,即distinct来返回不重复字段的条数(count(distinct id)),其原因是distinct只能返回他的目标字段,而无法返回其他字段 用法注意: 1.distinct[查询字段],必须放在要查询字段的开头,即放在第一个参数: 2.只能在SELECT 语句中使用,不能在 INSERT, DELETE, UPDATE 中使用: 3.DISTINCT 表示对后面的所有参数的拼接取 不重复的记录,即查出的参数拼接每行记录

  • MySQL数据库学习之去重与连接查询详解

    目录 1.去重 2.连接查询 使用where进行多表连接查询 内连接 - 等值连接 内连接 - 非等值连接 内连接 - 自连接 外连接 - 左右外连接 三表连接 1.去重 示例表内容参考此文章 有些 MySQL 数据表中可能存在重复的记录,有些情况我们允许重复数据的存在,但有时候我们也需要删除这些重复的数据. 例如:去重显示岗位信息: mysql> select distinct job from emp; +-----------+ | job | +-----------+ | CLERK

  • MySQL数据库之union,limit和子查询详解

    目录 1.where中的子查询 2.from子句后的子查询 3.union 4.limit查询 5.分页 1.where中的子查询 示例数据参见此文章 案例:查询比最低工资高的员工姓名和薪资 子查询,先查询子查询括号里的,再向上级进行查询 mysql> select ename,sal from emp where sal -> > -> (select min(sal) from emp); +--------+---------+ | ename | sal | +------

  • mysql中inner join和left join使用详解

    目录 区别 inner join 场景 inner join 场景 区别 返回不同1.inner join只返回两个表中联结字段相等的行2.left join的数量小于等于左表和右表中的记录数量. 数量不同1.inner join返回包括左表中的所有记录和右表中联结字段相等的记录.2.left join的数量以左表中的记录数量相同 记录属性不同1.inner join不足的记录属性会被直接舍弃2.left join不足的记录属性用NULL填充 inner join 场景 设计两张表: chann

  • Spring 3.x中三种Bean配置方式比较详解

    以前Java框架基本都采用了XML作为配置文件,但是现在Java框架又不约而同地支持基于Annotation的"零配置"来代替XML配置文件,Struts2.Hibernate.Spring都开始使用Annotation来代替XML配置文件了:而在Spring3.x提供了三种选择,分别是:基于XML的配置.基于注解的配置和基于Java类的配置. 下面分别介绍下这三种配置方式:首先定义一个用于举例的JavaBean. package com.chinalife.dao public cl

  • MySQL中sleep函数的特殊现象示例详解

    前言 MySQL中的系统函数sleep,实际应用的场景不多,一般用来做实验测试,昨天在测试的时候,意外发现sleep函数的一个特殊现象.如果在查询语句中使用sleep函数,那么休眠的时间跟返回的记录有关. 如下测试所示: mysql> create table test(id int); Query OK, 0 rows affected (0.03 sec) mysql> select *, sleep(6) from test; Empty set (0.00 sec) mysql>

  • MySQL中你可能忽略的COLLATION实例详解

    前言 MySQL 数据库的字符串类型有 CHAR.VARCHAR.BINARY.BLOB.TEXT.ENUM.SET.不同的类型在业务设计.数据库性能方面的表现完全不同,其中最常使用的是 CHAR.VARCHAR.今天我就带你深入了解字符串类型 CHAR.VARCHAR 的应用. CHAR 和 VARCHAR 的定义 CHAR(N) 用来保存固定长度的字符,N 的范围是 0 ~ 255,请牢记,N 表示的是字符,而不是字节.VARCHAR(N) 用来保存变长字符,N 的范围为 0 ~ 65536

  • MySQL中SQL Mode的查看与设置详解

    MySQL中SQL Mode的查看与设置 MySQL可以运行在不同的模式下,而且可以在不同的场景下运行不同的模式,这主要取决于系统变量 sql_mode 的值.本文主要介绍一下这个值的查看与设置,主要在Mac系统下. 对于每个模式的意义和作用,网上很容易找到,本文不做介绍. 按作用区域和时间可分为3个级别,分别是会话级别,全局级别,配置(永久生效)级别. 会话级别: 查看- select @@session.sql_mode; 修改- set @@session.sql_mode='xx_mod

  • Mysql中where与having的区别实例详解

    以一道题来做引子 牛客,SQL30 计算总和 OrderItems表代表订单信息,包括字段:订单号order_num和item_price商品售出价格.quantity商品数量. order_num item_price quantity a1 10 105 a2 1 1100 a3 1 200 a4 2 1121 a5 5 10 a6 1 19 a7 7 5 [问题]编写 SQL 语句,根据订单号聚合,返回订单总价不小于1000 的所有订单号,最后的结果按订单号进行升序排序. 提示:总价 =

随机推荐