嵌套查询

嵌套查询是指一个SELECT—FROM—WHERE查询块嵌入在另一个SELECT—FROM—WHERE查询块的WHERE子句中的查询

注意:

只有当连接查询投影列的属性来自于一个关系表时才能用嵌套查询等效实现。若连接查询投影列的属性来自于多个关系表,则不能用嵌套查询实现

一、简单子查询(非相关子查询)

简单子查询

简单子查询独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部查询,效率相对更高

当子查询返回的结果是一个集合时,外查询可能需要用到以下的一些关键字

表达式 含义
> ANY 只要大于其中一个即可
> ALL 必须大于所有结果 
< ANY 只要小于其中一个即可 
< ALL 必须小于所有结果 
>= ANY 只要大于或等于其中一个即可
>= ALL 必须大于或等于所有结果
<= ANY 只要小于或等于其中一个即可
<= ALL 必须小于或等于所有结果 
= ANY 只要等于其中一个即可
<> ANY  只要于其中一个不等即可
<> ALL  必须于所有结果都不等
 

查询成绩及格的学生的学号

SELECT sname AS 姓名
FROM student
WHERE sno IN
(
SELECT sno
FROM study
WHERE grade >= 60
)

查询成绩最高分学生的学号

SELECT sno AS 学号
FROM study
WHERE grade >= ALL
(
SELECT grade
FROM study
)

查询选修了C语言课程的学生的姓名

子查询实现方式:

SELECT sname
FROM student
WHERE sno IN
(
SELECT sno
FROM study
WHERE cno IN
(
SELECT cno
FROM course
WHERE cname='C语言'
)
) 笛卡尔积实现方式: SELECT sname
FROM student, study, course
WHERE student.sno = study.sno AND study.cno = course.cno AND course.cname = 'C语言'

二、相关子查询

相关子查询:

相关子查询的执行依赖于外部查询的数据,外部查询执行一行,子查询就执行一次,效率相对较低

用到相关子查询时可能用到以下两个关键字;注意,相关子查询不一定用到它们,即它们并不是相关子查询的标志

关键字 含义
EXISTS 依次取出外查询得到的每一个元组,代入子查询中计算。若该元组满足子查询的条件,则子查询返回一个布尔值 TRUE,并将该元组作为结果集的一个成员;否则返回布尔值 FALSE ,不作为结果集的一员
NOT EXISTS 依次取出外查询得到的每一个元组,代入子查询中计算。若该元组不满足子查询的条件,则子查询返回一个布尔值 TRUE,并将该元组作为结果集的一个成员;否则返回布尔值 FALSE ,不作为结果集的一员

将选修 操作系统 并且得分 超过85分 的学生的姓名显示出来

select sname
FROM student
WHERE EXISTS
(
SELECT *
FROM study
WHERE student.sno = study.sno AND grade >= 85 AND EXISTS
(
SELECT *
FROM course
WHERE study.cno = course.cno AND cname = '操作系统'
)
)

将没有选修操作系统的学生姓名显示出来

=======================================================================================================

分析:没有选修操作系统的学生 :(TRUE(学生(没有选择操作系统))) ===等价于===> (FALSE(学生(选修了操作系统)))

(TRUE(学生(没有选择操作系统)))虽然从思维上很好理解,但是如何证明一个学生没有选择操作系统?这似乎不是一件简单的事情,因为元组是一条一条验证的,假如一个学生选修了操作系统和C语言,当遍历该学生选修了操作系统时确实可以排除该学生的姓名,但是当遍历到该学生选修了C语言的这条记录时该何去何从呢?在记录中,该记录中该学生确实没有选修操作系统!因此代码上第一种方法是极其难以实现的,因此我们选择第二种

=======================================================================================================

select sname
FROM student
WHERE NOT EXISTS
(
SELECT *
FROM study
WHERE student.sno = study.sno AND EXISTS
(
SELECT *
FROM course
WHERE study.cno = course.cno AND cname = '操作系统'
)
)

将选修了全部课程的学生的姓名显示出来

=======================================================================================================

(TRUE(学生(选修了全部课程)))===等价于===>(学生(FALSE(课程(该学生没有选修))))

用自然语言描述即为:

对于任意一门课程,该学生都选修了 ===等价于===>不存在这样一门课程,这个课程没有被该学生选修

存在于这样一个学生,他选修的课包含了学校开的所有课 ===等价于===>不存在这样一个学生,学校开的所有课不被他选修的课所包含

=======================================================================================================

SELECT sname
FROM student
WHERE NOT EXISTS
(
SELECT *
FROM course
WHERE NOT EXISTS
(
SELECT *
FROM study
WHERE sno = student.sno AND cno = course.cno
)
) 或 SELECT sname
FROM student
WHERE NOT EXISTS
(
SELECT *
FROM course
WHERE cno NOT IN
(
SELECT cno
FROM study
WHERE student.sno = study.sno
)
)

查询一个学生y,该学生至少选修了另外一个学生x选修的全部课程

=======================================================================================================

分析:

不存在这样的一门课程,该课程被x选修了,而没有被y选修

=======================================================================================================

SELECT DISTINCT sno
FROM study X
WHERE NOT EXISTS
(
SELECT *
FROM study Y
WHERE y.sno = '03061' AND NOT EXISTS
(
SELECT *
FROM study z
WHERE z.sno = x.sno AND z.cno = y.cno
)
)

MySQL入门,第八部分,多表查询(二)的更多相关文章

  1. MySQL入门(4)——操作数据表

    MySQL入门(4)--操作数据表 创建数据库 CREATE [TEMPORARY] TABLE [IF NOT EXISTS] 数据库名 [(create_definition,...)] [tab ...

  2. 数据库SQL语言从入门到精通--Part 6--单表查询(快来PICK)

    数据库从入门到精通合集(超详细,学习数据库必看) 查询操作是SQL语言中很重要的操作,我们今天就来详细的学习一下. 一.数据查询的语句格式 SELECT [ALL|DISTINCT] <目标列表 ...

  3. mysql学习(十)多表查询

    多表查询时,要给表名起别名,给字段名其别名(当两个表含有重复字段时) select p.name, c.name, pid from products p, cats c;//得到的结果为笛卡尔乘积 ...

  4. MySql语句常用命令整理---多表查询

    首先第一张表还是我们单表查询之前用到t_employee,我们在另外新建一个表t_dept(部门表)建表命令如下: drop table if exists t_dept; CREATE TABLE ...

  5. MYSQL 外键 on语句 多表查询

    外键约束 创建外键 --- 每一个班主任会对应多个学生 , 而每个学生只能对应一个班主任 ----主表 CREATE TABLE ClassCharger( id TINYINT PRIMARY KE ...

  6. mysql增删改查、连表查询、常用操作

    一.建表 1.最简单的建表CREATE TABLE user(id int,name char(20),age int); 2.带主键带注释和默认值创建表CREATE TABLE  user(id I ...

  7. MySQL数据库(4)- 多表查询、可视化工具Navicat的使用、设计模式MVC

    一.多表查询 准备工作:创建两张表,部门表(department).员工表(employee),代码和表格如下: # 创建表 create table department( id int, name ...

  8. 黑马MySQL数据库学习day03 级联 多表查询 连接和子查询 表约束

    /* 存在外键的表 删表限制: 1.先删除从表,再删除主表.(不能直接删除主表,主表被从表引用,尽管实际可能还没有记录引用) 建表限制: 1.必须先建主表,再建从表(没有主表,从表无法建立外键关系) ...

  9. MySQL基础(三)多表查询(各种join连接详解)

    Mysql 多表查询详解 一.前言 二.示例 三.注意事项 一.前言 上篇讲到Mysql中关键字执行的顺序,只涉及了一张表:实际应用大部分情况下,查询语句都会涉及到多张表格 : 1.1 多表连接有哪些 ...

  10. MySQL优化:如何避免回表查询?什么是索引覆盖? (转)

    数据库表结构: create table user ( id int primary key, name varchar(20), sex varchar(5), index(name) )engin ...

随机推荐

  1. Button相关设置

    2020-03-11 每日一例第4天 1.添加按钮1-6,并修改相应的text值:  2.窗体Load事件加载代码: private void Form1_Load(object sender, Ev ...

  2. C++基础 学习笔记之一:源代码的格式化

    C++基础 学习笔记之一:源代码的格式化 1. 源代码中的标记与空白 C++中的语句是以分号表示语句的结束.在C++中空格和回车以及制表符均为相同作用,即三者通常可以互相替代. 例如可以将一个简单的m ...

  3. Vue 学习笔记(四)

    一.路由简单示例 HTML <script src="https://unpkg.com/vue/dist/vue.js"></script> <sc ...

  4. HDU 5448 Marisa’s Cake

    给定一个由n个整点构成的凸多边形,求从n个点里任意选不少于3个点组成的所有凸多边形的面积之和,显然整点构成的多边形面积一定是0.5的整数倍,所以题目需要你算出答案的2倍 mod1000000007的值 ...

  5. Blazor-断开连接后重新加载浏览器

    在大多数情况下,Blazor将与以前相同的线路上重新连接到服务器.但有时无法重新连接,需要重新加载web浏览器才能使网站重新工作.如果服务器回收应用程序池,则需要手动重新加载页面在没有调试的情况下在I ...

  6. [SQL]3.26--175+176+177+178+180+181+182

    175.组合两个表 题目 Code SELECT FirstName, LastName, City, State FROM Person LEFT JOIN Address --由于需要Person ...

  7. ajax结合sweetalert弹出框删除数据

    思路:

  8. C语言实现strcat / strlen / strcmp / strcpy

    主要考虑两点: 返回值对使用的便利性. 边界,null的判断. strcat char *m_strcat(char *des, const char *src) { assert((des != N ...

  9. word2vec 和 glove 模型的区别

    2019-09-09 15:36:13 问题描述:word2vec 和 glove 这两个生成 word embedding 的算法有什么区别. 问题求解: GloVe (global vectors ...

  10. [ex-kmp] HDU 2019 Multi-University Training Contest 5-string matching

    string matching Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others ...