Exists子查询

Exists的特点

1.在执行create或drop语句前,可以使用exists语句来判断数据库对象是否存在,返回值是true或false

drop table if exists student; 意思是如果存在表student则删除!否则不删除!

Create table if not exists student; 意思是如果不存在表student则创建,否则不创建!

2.exists还可以作为where条件的子查询

Select ..... from 表名 where exists (子查询);

意思是:

如果子查询有结果,则返回值为true,继续执行外层的查询语句;

如果子查询没有结果,则返回值是false,外层的查询语句不会执行。

-- 检查“高等数学-1” 课程最近一次考试成绩

-- 如果有 80分以上的成绩,显示分数排在前5名的学员学号和分数

-- 不使用exists

-- 01.查询“高等数学-1” 课程 对应的编号

SELECT subjectNo FROM `subject` WHERE SubjectName='高等数学-1'

-- 02.查询最近的考试成绩

SELECT MAX(ExamDate)

FROM result

WHERE SubjectNo=(SELECT subjectNo

FROM subject

WHERE SubjectName='高等数学-1')

-- 03. 在02的基础上 加条件 成绩大于80

SELECT * FROM result

WHERE ExamDate=(SELECT MAX(ExamDate)

FROM result

WHERE SubjectNo=(SELECT subjectNo FROM `subject`

WHERE SubjectName='高等数学-1'))

AND StudentResult>80

-- 04.优化

SELECT studentNo,StudentResult FROM result

WHERE ExamDate=(SELECT MAX(ExamDate)

FROM result

WHERE SubjectNo=(SELECT subjectNo FROM `subject`

WHERE SubjectName='高等数学-1'))

AND StudentResult>80

ORDER BY StudentResult DESC

LIMIT 0,5

-- 使用exists

-- 检查“高等数学-1” 课程最近一次考试成绩

-- 如果有 80分以上的成绩,显示分数排在前5名的学员学号和分数

-- 01.查询“高等数学-1” 课程 对应的编号

SELECT subjectNo FROM `subject` WHERE SubjectName='高等数学-1'

-- 02.查询最近的考试成绩

SELECT MAX(ExamDate)

FROM result

WHERE SubjectNo=(SELECT subjectNo FROM `subject`

WHERE SubjectName='高等数学-1')

-- 03.查询学号和成绩

SELECT StudentNo,StudentResult FROM result

WHERE EXISTS(SELECT * FROM result

WHERE subjectNo=(SELECT subjectNo FROM `subject`

WHERE SubjectName='高等数学-1')

AND ExamDate=(SELECT MAX(ExamDate) FROM result

WHERE SubjectNo=(SELECT subjectNo FROM `subject`

WHERE SubjectName='高等数学-1'))

AND StudentResult>80)

AND subjectNo=(SELECT subjectNo FROM `subject`

WHERE SubjectName='高等数学-1')

AND ExamDate=(SELECT MAX(ExamDate) FROM result

WHERE SubjectNo=(SELECT subjectNo FROM `subject`

WHERE SubjectName='高等数学-1'))

ORDER BY StudentResult DESC

LIMIT 0,5

Not Exists子查询

-- 检查“高等数学-1”课程最近一次考试成绩

-- 如果全部未通过考试(60分及格),认为本次考试偏难,计算的该次考试平均分加5分

-- 01.查询“高等数学-1” 课程 对应的编号

SELECT subjectNo FROM `subject` WHERE SubjectName='高等数学-1'

-- 02.查询最近的考试成绩

SELECT MAX(ExamDate)

FROM result

WHERE SubjectNo=(SELECT subjectNo

FROM `subject`

WHERE SubjectName='高等数学-1')

-- 03.查询成绩大于60的 反着来

SELECT StudentResult

FROM result

WHERE StudentResult>60

AND SubjectNo=(SELECT subjectNo

FROM `subject`

WHERE SubjectName='高等数学-1')

AND ExamDate=(SELECT MAX(ExamDate)

FROM result

WHERE SubjectNo=(SELECT subjectNo

FROM `subject`

WHERE SubjectName='高等数学-1'))

-- 04. 如果全部未通过考试,考试平均分加5分

SELECT AVG(StudentResult)+5

FROM result

WHERE NOT EXISTS(SELECT StudentResult

FROM result

WHERE StudentResult>60

AND SubjectNo=(SELECT subjectNo

FROM `subject`

WHERE SubjectName='高等数学-1')

AND ExamDate=(SELECT MAX(ExamDate)

FROM result

WHERE SubjectNo=(SELECT subjectNo

FROM `subject`

WHERE SubjectName='高等数学-1')))

AND SubjectNo=(SELECT subjectNo

FROM `subject`

WHERE SubjectName='高等数学-1')

AND ExamDate=(SELECT MAX(ExamDate)

FROM result

WHERE SubjectNo=(SELECT subjectNo

FROM `subject`

WHERE SubjectName='高等数学-1'))

-- 如果有 年级名称是大二 的学生,就 查询出 年级名称是大一的 所有学生信息

-- 01.先查询出 对应的年级编号

SELECT GradeId FROM grade WHERE GradeName='大一'

SELECT GradeId FROM grade WHERE GradeName='大二'

-- 02.在学生表中是否存在 年级名称是大二 的学生

SELECT *

FROM student

WHERE gradeID=(SELECT GradeId

FROM grade

WHERE GradeName='大二')

-- 03.如果有查询出 年级名称是大一的 所有学生信息

SELECT *

FROM student

WHERE EXISTS(SELECT *

FROM student

WHERE gradeID=(SELECT GradeId

FROM grade

WHERE GradeName='大二'))

AND GradeId=(SELECT GradeId

FROM grade

WHERE GradeName='大一')

Exists与IN , Not Exists与Not IN 的区别

image

1. IN和Not IN 做的是一个区间的判断,查询数据是否在区间内

Exists 和 Not Exists 都是根据查询语句返回 true 或者 false !

2. 例子:

select a.*

from A a

where a.id

in(select id from B)

如果:

A表中有1000条数据

B表中有1000条数据

分析步骤:

01\. select id from B 会查询出B表中的所有id,然后缓存起来,共1000条(因为使用in 会先执行子查询)

02.然后分别拿A表中的每一个id和B表中的1000个id进行比较,也就是比较了 1000*1000次

03.这样效率是非常慢的

04.如果B表中只有100或者10条数据(只是举例说明数据量小),那么就会比较1000*10

这样相对来说效率会高点!

结论:

子查询中涉及的表(B)数据量小于 主查询中涉及的表(A)数据量 时,使用In来查询!可以提高效率

In 查询做的是 外表和内表的hash连接

hash连接就是 以 外层查询的表作为hash table ,内层查询的表在hash table中查询数据!

很显然,如果内层查询的数量大 ,查询效率就慢,查询数据量小,效率就高!

例子:

select a.*

from A a

where exists (select id

from B b

where a.id=b.id)

如果:

A表中有1000条数据

B表中有1000条数据

分析步骤:

1. 使用了exists(会以外层查询为驱动)上面的sql语句只会执行1000次(因为A表中有多少条数据,就会执行几次)

2. exists查询不需要数据的结果集,只需要返回true或者false

结论:

子查询中涉及的表(B)数据量大于 主查询中涉及的表(A)数据量时,使用exists来查询!可以提高效率

Exists查询做的是loop循环

如果子查询中涉及的表(B)数据量 和 主查询中涉及的表(A)数据量 差不多时,建议使用IN来查询!

因为In查询是在内存中的查询,exists需要查询数据库,所以内存中的查询肯定比查询数据库性能高!

05.not exists 在任何时候都比not in 效率高!

因为not in 那么内外表都进行[全表扫描],没有用到索引!而not exists的子查询仍然可以用到索引!

any,

some,all的使用

SELECT *

FROM student

WHERE studentname

IN(SELECT studentName FROM student)

-- 使用any(只要是在区间就行) 替换in

SELECT *

FROM student

WHERE studentname=ANY(SELECT studentName FROM student)

-- all 满足子查询中编号最大的

SELECT *

FROM student

WHERE studentNo>ALL(SELECT studentNo

FROM student

WHERE studentNo IN(1014,1001,1002))

-- any 满足子查询中编号最小的

SELECT *

FROM student

WHERE studentNo>ANY(SELECT studentNo

FROM student

WHERE studentNo IN(1014,1001,1002))

-- 和 any 效果一致

SELECT * FROM student WHERE studentNo>SOME

分组查询

-- 分组 group by

-- 01. 查询 每门课程的名称 以及平均分

-- 并且按照平均分降序排列

SELECT subjectName,AVG(StudentResult)

FROM `result` r,`subject` s

WHERE r.`SubjectNo`=s.`SubjectNo`

GROUP BY subjectName

ORDER BY AVG(StudentResult) DESC

-- 02.在上述案例中增加 条件 having

-- 平均分>73的 显示

SELECT subjectName,AVG(StudentResult)

FROM `result` r,`subject` s

WHERE r.`SubjectNo`=s.`SubjectNo`

GROUP BY subjectName

HAVING AVG(StudentResult)>73

ORDER BY AVG(StudentResult) DESC

-- 03.统计每个年级的男女人数 多列进行分组

SELECT gradeid '年级编号',COUNT(sex) '性别人数',sex '性别'

FROM student

WHERE sex IS NOT NULL

AND gradeid IS NOT NULL

GROUP BY gradeid,sex

-- 04. 找出每个课程成绩的前三名

SELECT *

FROM result r1

WHERE (SELECT COUNT(1)

FROM result r2

WHERE r1.subjectNo=r2.`SubjectNo`

AND r1.studentresult

ORDER BY subjectNo,studentResult DESC

多表连接查询

比如之前写的小例子,查询学生的成绩,我们获取的是学生编号和成绩!

但是如果获取了学生姓名和成绩岂不是更好? 但是学生姓名和成绩不在一张表中!

这时候就需要我们的连接查询!

常用的连接查询方式:

内连接

外连接

内连接

内连接是典型的最常用的连接查询! 特点就是两个表中存在主外健关系时,通常使用!查询两张表中共同的数据!内连接的实现方式有两种:

在where条件中指定连接条件,比如 查询学生姓名以及对应的年级名称

Select studentName,gradeName

From student,grade

Where student.gradeId=grade.gradeId

2.在form 子句中增加 inner join 表 on 关系,比如查询学生姓名,科目名称以及考试成绩

SELECT studentName,subjectName,studentresult

FROM student s

INNER JOIN result r ON s.studentNo=r.studentNo

INNER JOIN `subject` su ON su.subjectNo=r.subjectNo

注意点:

001.inner可以省略

002.inner join 用来连接两个表

003.on用来设置条件

004. s r su是用的别名

外连接

外连接查询是至少返回一个表中的所有记录,根据匹配条件有选择地返回另一张表的数据!外连接有主表和从表的概念!以主表为准匹配从表的数据,符合连接条件的数据直接返回到结果集中,不符合的数据将被赋予null之后再返回到结果集中!外连接查询又分为:

1.左外连接 Left outer join

以左表为主表,从表(右边的表)中如果没有匹配的数据返回null

例子1: 查询学生的姓名,考试科目以及成绩!

SELECT studentName,subjectNo,studentResult

FROM student s

LEFT JOIN result r ON r.`studentNo`=s.`studentNo`

例子2:查询所有科目对应的学生成绩

SELECT subjectName,s.subjectNo,studentResult

FROM `subject` s

LEFT JOIN result r ON s.`SubjectNo`=r.`SubjectNo`

2.右外连接 right outer join

以右表为主表,从表(左边的表)中如果没有匹配的数据返回null

例子:查询年级名称和学生名称 两个结果是否一致?

SELECT gradeName,studentName

FROM grade

RIGHT JOIN student ON grade.`GradeID`=student.`GradeId`

SELECT gradeName,studentName FROM grade

INNER JOIN student ON grade.`GradeID`=student.`GradeId`

大千世界,求同存异;相遇是缘,相识是份,相知便是“猿粪”(缘分)

From MZou

mysql 高级查询词_Mysql高级查询语句相关推荐

  1. MySQL第九章索引_MySQL高级(索引优化+慢查询定位)

    一.先谈谈事务 1. ACID特性 1.1 原子性: 事务是最小的执行单位,不允许分割.事务的原子性确保动作要么全部完成,要么完全不起作用: 1.2 一致性: 执行事务前后,数据库从一个一致性状态转换 ...

  2. mysql 高级查询总结_MySQL高级查询总结

    (一)模糊查询 - 1.-like: mysql> select name as "姓名" from score where name like '张%'; +------- ...

  3. mysql高级查询 二_MySQL高级查询(二)

    EXISTS 和NOT EXISTS子查询 EXISTS子查询 语法: SELECT --- FROM 表名 WHERE EXISTS (子查询); 例: SELECT `studentNo` AS ...

  4. mysql 关联查询慢_mysql慢查询语句分析总结

    我们经常会接触到MySQL,也经常会遇到一些MySQL的性能问题.我们可以借助慢查询日志和explain命令初步分析出SQL语句存在的性能问题 通过SHOW FULL PROCESSLIST查看问题 ...

  5. mysql去重复查询 性能_MySQL中distinct语句去查询重复记录及相关的性能讨论_MySQL...

    在 MySQL 查询中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出不同(distinct)的值. 关键词 DISTINCT 用于返回唯一不同的值,就是去重啦.用法也很简单: SELE ...

  6. mysql去重复查询 性能_MySQL中distinct语句去查询重复记录及相关的性能讨论

    在 MySQL 查询中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出不同(distinct)的值. 关键词 DISTINCT 用于返回唯一不同的值,就是去重啦.用法也很简单: SELE ...

  7. mysql 慢日志 作用_MySQL慢查询日志的作用和开启

    前言 MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中.lon ...

  8. mysql 查询重写_mysql 学习 - 查询重写规则

    条件化简 我们编写的查询语句的搜索条件本质上是一个表达式,这些表达式可能比较繁杂,或者不能高效的执行,MySQL的查询优化器会为我们简化这些表达式. 移除不必要的括号 有时候表达式里有许多无用的括号, ...

  9. mysql慢查询单位_MySQL慢查询

    MySQL的慢查询,全名是慢查询日志,是MySQL提供的一种日志记录,用来记录在MySQL中响应时间超过阀值的语句.具体环境中,运行时间超过long_query_time值的SQL语句,则会被记录到慢 ...

最新文章

  1. LeetCode简单题之数组的相对排序
  2. BZOJ 2456 mode
  3. mysql三大范式_MySQL学习笔记
  4. 【牛客 - 283H】图论一顿套模板(思维转化,Dijkstra)
  5. python的lib文件夹_python遍历文件夹os.path与pathlib
  6. 基于JavaSpringMVC+Mybatis+Jquery高校毕业设计管理系统设计和实现
  7. 简单解决Ubuntu修改locale的问题
  8. 对一道if-else相关的程序题的简单分析
  9. 为什么每个人都有发旋?
  10. 替代传统按键方案 单通道感应TTP223E-BA6 TTP223E-CA6 TTP223E-HA6 单按键触摸检测IC
  11. 安卓简单的通用文本编辑器介绍
  12. Required request body is missing 报错解决
  13. android判断系统版本号,Android获取手机型号/系统版本号/App版本号等信息实例讲解...
  14. Python爬虫教程(一):爬虫
  15. 2023年全国最新二级建造师精选真题及答案2
  16. 去你的35岁危机|ONES 人物
  17. 气象数据免费下载(超级好用)
  18. 微信使用篇 - 如何在订阅号与服务号之间做出选择
  19. Scratch3.0 二次开发(4)修改界面字体大小
  20. datanode启不起来,报错:org.apache.hadoop.hdfs.server.datanode.Datanode:Enk pool service for:Block pool ()Da

热门文章

  1. 【2022年哈工大计算机系统课程大作业】程序人生-Hello‘s P2P
  2. Web Wiz Forums 12.03 ASP论坛程序源码
  3. 华南大学计算机保研,华南理工大学保研率19.6%,为其他985输送大量优秀生源
  4. Armv8/Armv9 MMU学习的28问
  5. 《游戏设计艺术(第2版)》——学习笔记(12)第12章 有些元素是游戏机制
  6. OC、OD、线与、线或、推挽概念
  7. LILYGO T-Wristband 可编程的手环
  8. 自用免费有趣的测试、学习API接口
  9. 矩阵论(八):矩阵微分与矩阵求导
  10. 加工中心宏程序c语言,加工中心宏程序编程实例与技巧方法