所谓复杂查询,指涉及多个表、具有嵌套等复杂结构的查询。这里简要介绍典型的几种复杂查询格式。

一、连接查询

连接是区别关系与非关系系统的最重要的标志。通过连接运算符可以实现多个表查询。连接查询主要包括内连接、外连接等。

假设有Student和Grade两个表如下:

+-----+--------+-------+ +-----+------------+--------+

| sID | sName | sDept | | gID | gCourse | gScore |

+-----+--------+-------+ +-----+------------+--------+

| 1 | Paul | CS | | 1 | Math | 87 |

| 2 | Oliver | MS | | 2 | English | 95 |

| 3 | Jack | SE | | 3 | Physics | 76 |

| 4 | Robin | CS | | 7 | Philosophy | 76 |

+-----+--------+-------+ +-----+------------+--------+

1.1 内连接

内连接(INNER JOIN)使用比较运算符进行表间列数据的比较操作,并列出这些表中与连接条件相匹配的数据行,组合成新的记录。

当比较操作符是=时,称为等值连接:

SELECT * FROM Student INNER JOIN Grade ON Student.sID = Grade.gID;

等价于

SELECT * FROM Student,Grade WHERE Student.sID = Grade.gID;

结果如下:

+-----+--------+-------+-----+---------+--------+

| sID | sName | sDept | gID | gCourse | gScore |

+-----+--------+-------+-----+---------+--------+

| 1 | Paul | CS | 1 | Math | 87 |

| 2 | Oliver | MS | 2 | English | 95 |

| 3 | Jack | SE | 3 | Physics | 76 |

+-----+--------+-------+-----+---------+--------+

可以看出,在内连接查询中,只有满足条件的记录才能出现在结果关系中。

1.2 外连接

与内连接不同的是,外连接返回的查询结果集中不仅包含符合连接条件的行,而且还包括左表(左连接)、右表(右连接)或两个表(全外连接)中的所有数据行。

1.2.1 左连接

LEFT JOIN(左连接),即LEFT OUTER JOIN,返回左表的全部记录,即使右表中没有对应匹配记录。

SELECT * FROM Student LEFT JOIN Grade ON Student.sID = Grade.gID;

结果如下:

+-----+--------+-------+------+---------+--------+

| sID | sName | sDept | gID | gCourse | gScore |

+-----+--------+-------+------+---------+--------+

| 1 | Paul | CS | 1 | Math | 87 |

| 2 | Oliver | MS | 2 | English | 95 |

| 3 | Jack | SE | 3 | Physics | 76 |

| 4 | Robin | CS | NULL | NULL | NULL |

+-----+--------+-------+------+---------+--------+

1.2.2 右连接

RIGHT JOIN(右连接),即RIGHT OUTER JOIN,返回右表的全部记录,即使左表中没有对应匹配记录。

SELECT * FROM Student RIGHT JOIN Grade ON Student.sID = Grade.gID;

结果如下:

+------+--------+-------+-----+------------+--------+

| sID | sName | sDept | gID | gCourse | gScore |

+------+--------+-------+-----+------------+--------+

| 1 | Paul | CS | 1 | Math | 87 |

| 2 | Oliver | MS | 2 | English | 95 |

| 3 | Jack | SE | 3 | Physics | 76 |

| NULL | NULL | NULL | 7 | Philosophy | 76 |

+------+--------+-------+-----+------------+--------+

1.2.3 全连接

FULL JOIN(全连接),即FULL OUTER JOIN,返回左表、右表的全部记录,即使没有对应的匹配记录。

**注意:**MySQL不支持FULL JOIN,不过可以通过UNION关键字来合并 LEFT JOIN 与 RIGHT JOIN来模拟。

SELECT * FROM Student LEFT JOIN Grade ON Student.sID = Grade.gID

UNION

SELECT * FROM Student RIGHT JOIN Grade ON Student.sID = Grade.gID

结果如下:

+------+--------+-------+------+------------+--------+

| sID | sName | sDept | gID | gCourse | gScore |

+------+--------+-------+------+------------+--------+

| 1 | Paul | CS | 1 | Math | 87 |

| 2 | Oliver | MS | 2 | English | 95 |

| 3 | Jack | SE | 3 | Physics | 76 |

| 4 | Robin | CS | NULL | NULL | NULL |

| NULL | NULL | NULL | 7 | Philosophy | 76 |

+------+--------+-------+------+------------+--------+

另外,如果在一个连接查询中涉及到的两个表是同一个表,这种查询称为自连接查询。为了防止产生二义性,自连接查询中通常对表使用别名。

二、子查询

子查询是指一个查询语句嵌套在另一个查询语句内部的查询。在 SELECT 子句中先计算子查询,子查询结果作为外层另一个查询的过滤条件。

子查询中常用的操作符有ANY、SOME、ALL、EXISTS、IN,也可以使用比较运算符。子查询可以添加到 SELECT、UPDATE 和 DELETE 语句中,而且可以进行多层嵌套。

2.1 在条件表达式中产生标量的子查询

SELECT *

FROM score

WHERE id = (SELECT event_id

FROM event

WHERE date='2015-07-01'

AND type='Q');

所谓标量,就是单个属性的一个原子值。当子查询出现在 WHERE 子句中的比较运算符(= ,>, >= ,< , <= ,<>)的右边,其输出结果应该只有一个才对。很容易理解,如果返回多条结果,就无法进行比较,系统就会报错。

又如:

SELECT * FROM teacher WHERE birth = MIN(birth); /*错误*/

这个查询是错的!因为MySQL不允许在子句里面使用统计函数,所以改用子查询:

SELECT *

FROM teacher

WHERE birth = (SELECT MIN(birth)

FROM teacher);

2.2 在条件表达式中产生集合的子查询

如果子查询的输出是一个结果集合,可以通过 ANY、ALL、IN 进行比较。

2.2.1 ANY与SOME

ANY和SOME关键字是同义词,表示满足其中任一条件。它们允许创建一个表达式对子查询的返回结果集进行比较:

SELECT num1

FROM t1

WHERE num1 > ANY(SELECT num2

FROM t2);

上面的子查询返回 t2 的 num2 列,然后将 t1 中的 num1 值与之进行比较,只要大于 num2 的任何一个值,即为符合查询条件的结果。

等价于:

SELECT num1

FROM t1

WHERE num1 > SOME(SELECT num2

FROM t2);

2.2.2 ALL

与ANY/SOME不同,使用ALL时需要同时满足所有内层查询的条件。

SELECT num1

FROM t1

WHERE num1 > ALL(SELECT num2

FROM t2);

上面的子查询还是返回 t2 的 num2 列,然后将 t1 中的 num1 值与之进行比较。但是只有大于所有 num2 值的 num1 才是符合查询条件的结果。

2.2.3 IN

IN关键字后接一个子查询,若在子查询结果集中,返回true,否则返回false。与之相对的是NOT IN。

SELECT num1

FROM t1

WHERE num1 IN (SELECT num2

FROM t2);

2.3 在条件表达式中测试空/非空的子查询

EXISTS关键字后接一个任意的子查询,系统对子查询进行运算以判断它是否返回行。

若至少返回一行,那么 EXISTS 的结果为 true,此时外层查询语句将进行查询;

若没有返回任何行,那么 EXISTS 的结果为 false,此时外层语句将不进行查询。

SELECT sName

FROM Student

WHERE EXISTS (SELECT *

FROM Grade

WHERE gScore < 60);

EXISTS和NOT EXISTS的结果只取决于是否会返回行,而不取决于这些行的内容。

2.4 关联子查询

一般的子查询只计算一次,其结果用于外层查询。但关联子查询需要计算多次。

子查询中使用了主查询中的某些字段,主查询每扫描一行都要执行一次子查询,这种子查询称为关联子查询(Correlated Subquery)。

SELECT sName

FROM Student

WHERE '450' NOT IN (SELECT courseID

FROM Course

WHERE sID = Student.sID);

上面的子查询中使用了 Student 表的 sID 字段。对于 Student 表中每一个 sID 都会执行一次子查询。

2.5 FROM子句中的子查询

子查询可以用括号括起来作为一个关系,从而出现在 FROM 列表中。由于子查询的结果关系没有正式的名字,故必须给它取一个别名。

SELECT *

FROM Grade,

(SELECT * FROM Student WHERE sDept='CS')x

WHERE x.sID=Grade.gID;

x 就是子查询的结果关系的别名。

三、合并查询结果

利用UNION或UNION ALL关键字,可以将多个 SELECT 语句的结果组合成单个结果集。合并时,两个表对应的列数和数据类型必须相同。

UNION:合并查询结果时,删除重复的记录,返回的行都是唯一的。

UNION ALL:合并查询结果时,不删除重复行。

3.1 UNION ALL

SELECT * FROM Student

UNION ALL

SELECT * FROM Student;

结果如下:

+-----+--------+-------+

| sID | sName | sDept |

+-----+--------+-------+

| 1 | Paul | CS |

| 2 | Oliver | MS |

| 3 | Jack | SE |

| 4 | Robin | CS |

| 1 | Paul | CS |

| 2 | Oliver | MS |

| 3 | Jack | SE |

| 4 | Robin | CS |

+-----+--------+-------+

3.2 UNION

SELECT * FROM Student

UNION

SELECT * FROM Student;

结果如下:

+-----+--------+-------+

| sID | sName | sDept |

+-----+--------+-------+

| 1 | Paul | CS |

| 2 | Oliver | MS |

| 3 | Jack | SE |

| 4 | Robin | CS |

+-----+--------+-------+

mysql的复杂查询_mysql复杂查询相关推荐

  1. mysql 内嵌查询_mysql嵌套查询_MySQL

    mysql嵌套查询_MySQL 一:创建ecs_goods表插入以下数据: +----------+------------------------------+--------+---------- ...

  2. 简单mysql 查询_MySQL简单查询详解

    MySQL的查询操作 单表查询:简单查询 多表查询:连接查询 联合查询 布尔条件表达式操作符= 等值比较 <=>:跟空值比较不会产生额外信息的等值比较 <>:不等值 <: ...

  3. mysql rand() 子查询_MySQL ------ 子查询(十三)

    查询(query):任何SQL 都是查询,但此术语一般指select 语句 子查询(subquery):嵌套在查询中的查询,MySQL4.1 引入对子查询的支持. 接下来得就比较有意思了,需要你对于表 ...

  4. mysql 最值复杂查询_MySQL高级查询

    我们使用SQL查询不能只使用很简单.最基础的SELECT语句查询.如果想从多个表查询比较复杂的信息,就会使用高级查询实现.常见的高级查询包括多表连接查询.内连接查询.外连接查询与组合查询等,今天我们先 ...

  5. mysql 组合查询_MySQL组合查询教程

    #MYSQL#这是我MySQL的第八篇教程.本篇主要介绍的是MySQL的组合查询的用法.在大多数的SQL查询中都只包含从一个或者多个表中返回数据的单条SELECT语句,MySQL其实也支持允许执行多条 ...

  6. 云数据库mysql 慢查询_Mysql慢查询

    一.简介 开启慢查询日志,可以让MySQL记录下查询超过指定时间的语句,通过定位分析性能的瓶颈,才能更好的优化数据库系统的性能. 二.参数说明 slow_query_log 慢查询开启状态 slow_ ...

  7. mysql 分号子查询_MySQL子查询详解

    子查询指一个查询语句嵌套在另一个查询语句内部的查询,这个特性从 MySQL 4.1 开始引入,在 SELECT 子句中先计算子查询,子查询结果作为外层另一个查询的过滤条件,查询可以基于一个表或者多个表 ...

  8. mysql分表全局查询_mysql如何查询多样同样的表/sql分表查询、java项目日志表分表的开发思路/按月分表...

    之前开发的一个监控系统,数据库的日志表是单表,虽然现在数据还不大并且做了查询sql优化,不过以后数据库的日志表数据肯定会越来越庞大,将会导致查询缓慢,所以把日志表改成分表,日志表可以按时间做水平分表, ...

  9. c mysql清理日志文件_MySQL 一般查询日志或者慢查询日志历史数据的清理

    general log&slow query log 对于MySQL的一般查询日志和慢查询日志,开启比较简单,其中公用的一个参数是log_output,log_output控制着慢查询和一般查 ...

最新文章

  1. Silverlight/Windows8/WPF/WP7/HTML5周学习导读(10月15日-10月21日)
  2. 解决Python中字典出现“TypeError: 'dict_keys' object does not support indexing”错误
  3. 玩转SpringBoot 2.x 之搭建 Actuator 和 SpringBoot Admin监控篇
  4. url安全处理函数+php,php常用的url处理函数汇总
  5. 14.5-全栈Java笔记:java.awt这些布局怎么写?|流式|边界|网格
  6. trunc函数_这几个舍入函数你都会用吗?
  7. 循序渐进 OSPF的详细剖析(二)
  8. html怎么截取部分图片,【原创】详解css用坐标来截取部分图片
  9. typecho图片插件_Typecho图片表情插件Smilies1.1.3更新
  10. 小爱音箱连接Windows蓝牙没有声音
  11. win10 截屏 快捷键(全屏直接保存、全屏间接保存、当前界面)
  12. cdd matlab 算法,求翻译 CDD修复算法
  13. 你想要的虚幻UE游戏人物模型素材都在这里,细致又齐全
  14. Python3-word文档操作(八):提取word文档中的图片方式一-利用docx库
  15. 数据挖掘并不遥远( 转载)
  16. vue下载pdf为空问题解决
  17. Android SQLite 数据库存储
  18. Android MVVM封装,MVVM: 这是一个android MVVM 框架,基于谷歌dataBinding技术实现
  19. ctp python接口实现 固定金额 止损 止盈
  20. docker文件过大,Docker容器引擎,迁移/var/lib/docker/到本机其它挂载分区或远程主机的某个分区。docker迁移

热门文章

  1. 接口幂等设计探索实践
  2. 作为一个有理想的程序员,必读的书都有哪些?
  3. [ASP.NET Core 3.1]浏览器嗅探解决部分浏览器丢失Cookie问
  4. .NET Core开发实战(第24课:文件提供程序:让你可以将文件放在任何地方)--学习笔记...
  5. .NET Core开发实战(第22课:异常处理中间件:区分真异常与逻辑异常)--学习笔记(上)...
  6. 动手造轮子:实现简单的 EventQueue
  7. .NET中生成动态验证码
  8. 微服务探索与实践—总述
  9. dotnetcore+vue+elementUI 前后端分离架 二(后端篇)
  10. 一个还算简单的微信消息SDK(基于.Net Standard 2.0)