mysql复杂查询(一)
所谓复杂查询,指涉及多个表、具有嵌套等复杂结构的查询。这里简要介绍典型的几种复杂查询格式。
一、连接查询
连接是区别关系与非关系系统的最重要的标志。通过连接运算符可以实现多个表查询。连接查询主要包括内连接、外连接等。
假设有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复杂查询(一)的更多相关文章
- Linux下MySQL慢查询分析mysqlsla安装使用
说明: 操作系统:CentOS 5.X 64位 MySQL版本:mysql-5.5.35 MySQL配置文件:/etc/my.cnf MySQL 数据库存放目录:/data/mysql 实现目的:开启 ...
- MySQL的查询计划中ken_len的值计算
本文首先介绍了MySQL的查询计划中ken_len的含义:然后介绍了key_len的计算方法:最后通过一个伪造的例子,来说明如何通过key_len来查看联合索引有多少列被使用. key_len的含义 ...
- mysql的查询、子查询及连接查询
>>>>>>>>>> 一.mysql查询的五种子句 where(条件查询).having(筛选).group by(分组). ...
- MySQL慢查询日志总结
慢查询日志概念 MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志 ...
- 【转】Mysql联合查询union和union all的使用介绍
Mysql的联合查询命令UNION和UNION ALL,总结了使用语法和注意事项,以及学习例子和项目例子,需要的朋友可以参考下 一.UNION和UNION ALL的作用和语法 UNION 用于合... ...
- mysql慢查询日志分析工具 mysqlsla(转)
mysql数据库的慢查询日志是非常重要的一项调优辅助日志,但是mysql默认记录的日志格式阅读时不够友好,这是由mysql日志记录规则所决定的,捕获一条就记录一条,虽说记录的信息足够详尽,但如果将浏览 ...
- Mysql慢查询和慢查询日志分析
Mysql慢查询和慢查询日志分析 众所周知,大访问量的情况下,可添加节点或改变架构可有效的缓解数据库压力,不过一切的原点,都是从单台mysql开始的.下面总结一些使用过或者研究过的经验,从配置以 ...
- [django/mysql] 使用distinct在mysql中查询多条不重复记录值的解决办法
前言:不废话.,直接进入正文 正文: 如何使用distinct在mysql中查询多条不重复记录值? 首先,我们必须知道在django中模型执行查询有两种方法: 第一种,使用django给出的api,例 ...
- MySQL 慢查询日志分析及可视化结果
MySQL 慢查询日志分析及可视化结果 MySQL 慢查询日志分析 pt-query-digest分析慢查询日志 pt-query-digest --report slow.log 报告最近半个小时的 ...
- mysql datetime查询异常
mysql datetime查询异常 异常:Value '0000-00-00 00:00:00' can not be represented as java.sql.Timestamp (2011 ...
随机推荐
- Js_字体滚动换颜色
<html><head><meta http-equiv="Content-Type" content="text/html; charse ...
- 软件测试_APP测试_兼容性测试
APP的兼容测试主要就是测试APP的安装.启动.运行.卸载测试,以及安装时间 .启动时间.CPU占用.内存占用.流量耗用.电量耗用等性能上的测试. 兼容性测试点: 一.内部兼容性: 1.与本地和其他主 ...
- 3.3V电源LDO
1:今天用到1颗3.3v的LDO,如图 输入输出都是3.3V,但是一个是做模拟电压,以后遇到这种情况可以这样使用. 2:二极管降压电路,1.8V转1.5V
- CentOS 6.8 安装Maven
1.下载maven安装包到developer文件目录下 2,解压缩maven,命令: -bin.tar.gz 3.配置maven路径到环境变量中 export JAVA_HOME=/usr/java/ ...
- TKmath Package gp数据类型
点,向量,方向 二维:gp_Pnt2d, gp_Vec2d, gp_Dir2d:它们的内部都存储 gp_XY 三维:gp_Pnt, gp_Vec, gp_Dir:它们的内部都存储 gp_XYZ 轴向与 ...
- 用 C 语言描述几种排序算法
排序算法是最基本且重要的一类算法,本文基于 VS2017,使用 C 语言来实现一些基本的排序算法. 一.选择排序 选择排序,先找到数组中最小的元素,然后将这个元素与数组的第一个元素位置互换(如果第一个 ...
- abcdocker 的博客
技术参考总结 abcdocker 的博客 09月 3 篇 20日 Centos7 图形化创建KVM 10日 Nginx 代理Google 进行*** 10日 mac 安装装逼神器cmatrix 08月 ...
- 1092. To Buy or Not to Buy (20)-map
给出两个字符串,判断第二个字符串中的字符是否都出现在第一个中. 是,则输出Yes,以及多余的字符的个数. 否,则输出No,以及缺失的个数. #include <iostream> #inc ...
- #个人博客作业Week1——浏览教材后提出的5个问题
1.对于MSF的团队模型,请问是团队中的哪个角色监督9项原则的实现?是否会浪费时间和精力在践行9项原则上?2.在调查用户需求和用户体验时如何让不同阶层的用户更多的参与度?3.想成为一位优秀的PM需要从 ...
- Redis学习笔记之入门基础知识——其他特性
1.订阅(subscribe)与发布(publish) 用户订阅某一个频道,频道发布新的信息时,会将信息告知用户 2.数据安全 1) 快照持久化(时间点转储,实质是数据副本) 操作:SAVA. ...