文章目录
1 简单查询
在MySQL中可以通过SQL语句来实现基本数据查询,SQL语句可以通过如下多种使用:查询所有字段数据、查询指定字段数据、避免重复数据查询、对结果进行排序和分组等查询。
数据库中可能包含数量庞大的表,表中可能包含无数的记录,如果没有两把刷子要获得所需的数据并非易事。在MySQL中,可以使用SELECT语句来查询数据,根据查询条件的不同,数据库系统会找到不同的数据,通过SELECT语句可以很方便地获取所需的信息。
在MySQL中,SELECT语句的基本语法形式如下:
SELECT field1 field2 … fieldn
FROM tablename
[WHERE CONDITION1]
[GROUP BY fieldm [HAVING CONDITION2]]
[ORDER BY fieldn [ASC|DESC]];
其中,filed1~fieldn参数表示需要查询的字段名;tablename参数表示表的名称;CONDITION1参数表示查询条件;fieldm参数表示按该字段中的数据进行分组;CONDITION2参数表示满足该表达式的数据才能输出;fieldn参数指按该字段中数据进行排序。排序方式由ASC和DESC两个参数指出;ASC参数表示按升序的顺序进行排序,是默认参数;DESC参数表示按降序的顺序进行排序。
1.1 查询所有字段数据
查询所有字段是指查询表中所有字段的数据,这种方式可以将表中所有字段的数据都查询出来。MySQL有两种方式可以查询表中的所有字段。
1. 列出表的所有字段。
通过SQL语句SELECT列出表的所有字段,具体语法形式如下:
SELECT field1,field2,…,fieldn FROM tablename;
其中,filed1~fieldn参数表示需要查询的字段名;tablename参数表示表的名称。
2. “*”符号表示所有字段。
查询所有字段数据,除了使用上面的方式外,还可以通过符号“*”来实现,具体语法形式如下:
SELECT * FROM tablename;
其中,符号“”表示所有字段名;tablename参数表示表的名称。与上一种方式相比,“”符号方式的优势比较明显,即可用该符号代替表中的所有字段,但是这种方式不够灵活,只能按照表中字段的固定顺序显示,不能随便改变字段的顺序。
1.2 查询指定字段数据
查询指定字段数据,只需修改关键字SELECT后的字段列表为指定字段即可。
SELECT field1,field2,…,fieldn FROM tablename;
例如,从班级表中查询班主任字段,SQL语句如下所示。
SELECT teacher FROM class;
如果关键字SELECT后面的字段不包含在所查询的表中,那么MySQL会报错。
mysql> create database school; #创建数据库school
mysql> use school; #选择数据库school
mysql> create table class(id int UNIQUE AUTO_INCREMENT, name varchar(128) UNIQUE, teacher varchar(64)); #创建表class,指定id 字段自增长
mysql> insert into class(id, name, teacher) values(1, '一班', 'Martin'),(2,'二班', 'Rock'),(3, '三班', 'Janny'),(4,'四班', 'Janny'); # 插入多条记录
mysql> select teacher from class ; #查询class表中的teacher 域
1.3 DISTINCT查询
当在MySQL中执行简单数据查询时,有时会显示出重复数据。为了实现查询不重复数据,MySQL提供了DISTINCT功能,SQL语法如下:
SELECT DISTINCT field1,field2,…,fieldn FROM tablename;
在上述语句中,关键字DISTINCT去除重复的数据。下面将通过一个具体的示例来说明如何实现查询不重复数据。
执行SQL语句SELECT,在数据库school中查询班级表 class 中teacher字段的数据。具体步骤如下:
mysql> create database school; #创建数据库school
mysql> use school; #选择数据库school
mysql> create table class(id int UNIQUE AUTO_INCREMENT, name varchar(128) UNIQUE, teacher varchar(64)); #创建表class,指定id 字段自增长
mysql> insert into class(id, name, teacher) values(1, '一班', 'Martin'),(2,'二班', 'Rock'),(3, '三班', 'Janny'),(4,'四班', 'Janny'); # 插入多条记录
mysql> select teacher from class ; #查询class表中的teacher 域,包含重复记录
mysql> select distinct teacher from class ; #查询class表中的teacher 域,去重
1.4 IN查询
有的时候,当我们需要查询的目标记录限定在某个集合中的时候,在MySQL中可以使用关键字IN来实现,关键字IN可以实现判断字段的数值是否在指定集合中,该关键字的具体语句形式如下:
SELECT field1,field2,…,fieldn
FROM tablename WHERE filedm IN(value1,value2,value3,…,valuen);
注:参数fieldn表示名称为tablename的表中的字段名,参数valuen表示集合中的值,通过关键字IN来判断字段fieldm的值是否在集合(value1,value2,value3,…,valuen)中,如果字段fieldm的值在集合中,就满足查询条件,该记录会被查询出来,否则不会被查询出来。
mysql> create database school; #创建数据库school
mysql> use school; #选择数据库school
mysql> create table class(id int UNIQUE AUTO_INCREMENT, name varchar(128) UNIQUE, teacher varchar(64)); #创建表class,指定id 字段自增长
mysql> insert into class(id, name, teacher) values(1, '一班', 'Martin'),(2,'二班', 'Rock'),(3, '三班', 'Janny'),(4,'四班', 'Janny'); # 插入多条记录
mysql> select * from class where teacher in ('Martin','Rock') ; #查询class表中的teacher 域是martin 和Rock 的记录
使用NOT IN可以反向查询非集合中的数据:
SELECT field1,field2,…,fieldn
FROM tablename WHERE filedm NOT IN(value1,value2,value3,…,valuen);
集合查询的注意: 集合中慎用 NULL。
在具体使用关键字IN时,查询的集合中如果存在NULL,则不会影响查询,NULL 存不存在的效果都一样;但如果使用关键字NOT IN,查询的集合中如果存在NULL,则不会查询到任何的结果。
1.5 BETWEEN AND查询
当我们需要查询指定范围内的数据(如: id 从0 到 100)的时候,MySQL提供了关键字BETWEEN AND,用来实现判断字段的数值是否在指定范围内的条件查询。该关键字的具体语法形式如下:
SELECT field1,field2,…,fieldn
FROM tablename WHERE fieldm BETWEEN minvalue AND maxvalue
在上述语句中,参数fieldn表示名称为tablename的表中的字段名,通过关键字BETWEEN和AND来设置字段field的取值范围,如果字段field的值在所指定的范围内,那么满足查询条件,该记录会被查询出来,否则不会被查询出来。
BETWEEN minvalue AND maxvalue,表示的是一个范围间的判断过程,只针对数字类型。
1.符合范围的数据记录查询。
通过关键字BETWEEN和AND设置查询范围,以实现查询语文成绩(字段Chinese)在80和90之间的学生,具体SQL如下:
mysql> create database school; #创建数据库school
mysql> use school; #选择数据库school
mysql> create table grade(id int UNIQUE AUTO_INCREMENT, name varchar(128) NOT NULL, math tinyint unsigned, chinese tinyint unsigned, english tinyint unsigned, create_date date); #创建成绩表 grade
mysql> insert into grade values(1, '甲', 80, 87, 91,'2020-02-03'),(2,'乙', 72, 64, 89,'2020-05-01'),(3, '丙', 54, 69, 87,'2020-04-21'),(4,'丁', 78, 79, 89, '2020-06-04'); # 插入多条记录
mysql> select * from class where chinese between 80 and 90 ; #查询成绩表中语文成绩在80 和 90 之间的学员记录
mysql> select * from grade where create_date between '2020-05-01' and '2020-06-04'
2. 不符合范围的数据记录查询。
通过关键字NOT设置反向查询非查询范围的条件,具体SQL语句如下:
SELECT name,chinese
FROM grade WHERE Chinese NOT BETWEEN 85 AND 90;
上面语句等同于:
select name,chinese from grade where chinese <85 or chinese >90;
1.6 LIKE模糊查询
当我们只想用字符串中间的一部分特征查找含有特征字串的信息时,MySQL提供了关键字LIKE来实现模糊查询,需要使用通配符,具体语法形式如下:
SELECT field1,field2,…,fieldn
FROM tablename WHERE fieldm LIKE value;
在上述语句中,参数tablename表示表名,参数fieldn表示表中的字段名字,通过关键字LIKE来判断字段field的值是否与value字符串匹配,如果相匹配,则满足查询条件,该记录就会被查询出来;否则就不会被查询出来。
在MySQL中,字符串必须加上单引号(’’)和双引号(″″)。由于关键字LIKE可以实现模糊查询,因此该关键字后面的字符串参数除了可以使用完整的字符串外,还可以包含通配符。LIKE关键字支持的通配符如下表所示。

1.查找某个字段含有‘三’字的记录:
SELECT * FROM class WHERE teacher LIKE ‘%三%’;
注意: 将会把teacher字段为“三爷”,“张三”,“张猫三”、“三脚猫”,“唐三藏”等等含“三”的记录全找出来。
2.查找teacher字段中既有“三”又有“猫”的记录,请使用and条件
SELECT * FROM class WHERE teacher LIKE ‘%三%’ AND teacher LIKE ‘%猫%’;
3.查询teacher字段中既有“三”又有“猫”的记录,同时“猫”在“三”之后的记录
SELECT * FROM class WHERE teacher LIKE ‘%三%猫%’;
注意: 虽然能搜索出“三脚猫”,但不能搜索出符合条件的“张猫三”。
4.只找出“唐三藏”这样teacher为三个字且中间一个字是“三”的;
SELECT * FROM [user] WHERE u_name LIKE ‘_三_’;
注意:_表示任意单个字符。匹配单个任意字符,它常用来限制表达式的字符长度语句:(可以代表一个中文 字符)
5.只找出“三脚猫”这样teacher为三个字且第一个字是“三”的;
SELECT * FROM class WHERE teacher LIKE ‘三__’;
下面看更多的示例:
1. 带有“%”通配符的查询:
(1)查询字段teacher中以字母Ma开头的数据记录,具体SQL语句如下:
SELECT teacher FROM class WHERE teacher LIKE 'Ma%';
(2)MySQL不区别大小写,上述SQL语句可以修改如下:
SELECT * FROM class WHERE teacher LIKE 'MA%';
(3)如果想查询不是以字母Ma开头的全部老师,可以执行逻辑非运算符(NOT),具体SQL语句如下:
SELECT teacher FROM class WHERE teacher NOT LIKE 'ma%';
mysql> create database school; #创建数据库school
mysql> use school; #选择数据库school
mysql> create table class(id int UNIQUE AUTO_INCREMENT, name varchar(128) UNIQUE, teacher varchar(64)); #创建表class,指定id 字段自增长
mysql> insert into class(id, name, teacher) values(1, '一班', 'Martin'),(2,'二班', 'Rock'),(3, '三班', 'Janny'),(4,'四班', 'Janny'); # 插入多条记录
mysql> SELECT teacher FROM class WHERE teacher LIKE '%Ma%'; #查询class表中的teacher 域,包含重复记录
mysql> SELECT name FROM class WHERE name NOT LIKE 'ma%';
2. 带有“_”通配符的查询。
(1)查询字段teacher中第二个字母为A的数据记录,具体SQL语句如下:
SELECT * FROM class WHERE teacher LIKE '_A%';
(2)如果想查询第二个字母不是A的全部老师,可以执行逻辑非运算符(NOT),具体SQL语句如下:
SELECT * FROM class WHERE NOT teacher LIKE '_A%';
(3)如果想查询第二个字母不是A的全部老师,也可以用以下SQL语句查询:
SELECT * FROM class WHERE teacher NOT LIKE '_A%';
3.使用LIKE关键字查询其他类型数据。
(1)执行SQL语句SELECT,查询grade表字段english带有数字9的全部学生,具体SQL语句如下:
SELECT name,english FROM grade WHERE english LIKE '%9%';
(2)对于LIKE关键字,如果匹配“%%”,就表示查询所有数据记录。
SELECT name FROM grade WHERE name LIKE '%%';
mysql> create database school; #创建数据库school
mysql> use school; #选择数据库school
mysql> create table grade(id int UNIQUE AUTO_INCREMENT, name varchar(128) NOT NULL, math tinyint unsigned, chinese tinyint unsigned, english tinyint unsigned, create_date date); #创建成绩表 grade
mysql> insert into grade values(1, '甲', 80, 87, 91,'2020-02-03'),(2,'乙', 72, 64, 89,'2020-05-01'),(3, '丙', 54, 69, 87,'2020-04-21'),(4,'丁', 78, 79, 89, '2020-06-04'); # 插入多条记录
mysql> select * from grade where english like '9_' ; #查询英语成绩是90 - 99 的记录
1.7 对查询结果排序
在MySQL中,从表中查询出的数据可能是无序的,或者其排列顺序不是用户所期望的顺序,为了使查询结果的顺序满足用户的要求,可以使用关键字ORDER BY对记录进行排序,其语法形式如下:
SELECT field1, field2, field3, …, fieldn
FROM tablename ORDER BY fieldm [ASC|DESC]
在上述语句中,参数tablename表示所要进行排序的表名,参数fieldn表示表中的字段名字,参数fieldm表示按照该字段进行排序;ASC表示按升序进行排序;DESC表示按降序进行排序。默认的情况下按ASC进行排序。
注意:如果存在一条记录字段的值为空值(NULL),那么按升序排序时,含空值的记录将最先显示,可以理解为空值是该字段的最小值;按降序排列时,字段为空值的记录将最后显示。
执行SQL语句SELECT,查询表grade中所有的数据记录,按照语文成绩(字段chinese)升序排序,具体SQL语句如下:
SELECT id,name,chinese FROM class ORDER BY chinese ASC;
mysql> create database school; #创建数据库school
mysql> use school; #选择数据库school
mysql> create table grade(id int UNIQUE AUTO_INCREMENT, name varchar(128) NOT NULL, math tinyint unsigned, chinese tinyint unsigned, english tinyint unsigned, create_date date); #创建成绩表 grade
mysql> insert into grade values(1, '甲', 80, 87, 91,'2020-02-03'),(2,'乙', 72, 64, 89,'2020-05-01'),(3, '丙', 54, 69, 87,'2020-04-21'),(4,'丁', 78, 79, 89, '2020-06-04'); # 插入多条记录
mysql> SELECT id,name,chinese FROM class ORDER BY chinese ASC; #按升序的方式查询学员记录
1.8 简单分组查询
MySQL软件提供了5个统计函数来帮助用户统计数据,可以使用户很方便地对记录进行统计数、计算和、计算平均数、计算最大值和最小值,而不需要查询所有数据。
在具体使用统计函数时,都是针对表中所有记录数或指定特定条件(WHERE子句)的数据记录进行统计计算。在现实应用中,经常会先把所有数据记录进行分组,再对这些分组后的数据记录进行统计计算。
MySQL通过SQL语句GROUP BY来实现,分组数据查询语法如下:
SELECT function()[,filed ]
FROM tablename WHERE CONDITION GROUP BY field;
在上述语句中,参数field表示某字段名,通过该字段对名称为tablename的表的数据记录进行分组。
注意:在具体进行分组查询时,分组所依据的字段上的值一定要具有重复值,否则分组没有任何意义。
五个统计函数简介:
1.统计数量。
COUNT(*):该种方式可以实现对表中记录进行统计,不管表字段中包含的是NULL值还是非NULL值。
COUNT(field):该种方式可以实现对指定字段的记录进行统计,在具体统计时将忽略NULL值。
2. 统计计算平均值。
该函数只有一种使用方式。
AVG(field)使用方式:该种方式可以实现对指定字段的平均值进行计算,在具体统计时将忽略NULL值。
3. 统计计算求和。
该函数只有一种使用方式。
SUM(field)使用方式:该种方式可以实现计算指定字段值之和,在具体统计时将忽略NULL值。
4. 统计最大值。
该函数只有一种使用方式。
MAX(field)使用方式:该种方式可以实现计算指定字段值中的最大值,在具体统计时将忽略NULL值。
5. 统计最小值。
该函数只有一种使用方式。
MIN(field)使用方式:该种方式可以实现计算指定字段值中的最小值,在具体统计时将忽略NULL值。
mysql> create database school; #创建数据库school
mysql> use school; #选择数据库school
mysql> create table grade(id int UNIQUE AUTO_INCREMENT, name varchar(128) NOT NULL, math tinyint unsigned, chinese tinyint unsigned, english tinyint unsigned, class_id int NOT NULL); #创建成绩表 grade
mysql> insert into grade values(1, '甲', 80, 87, 91, 1),(2,'乙', 72, 64, 89,2),(3, '丙', 54, 69, 87,2),(4,'丁', 78, 79, 89, 1); #插入多条记录
mysql> select class_id, sum(math) from grade group by class_id; #对两个班级的数学成绩进行统计
mysql> select class_id, avg(math), avg(chinese), avg(english) from grade group by class_id; #统计平均分,会忽略掉NULL 记录
1.9 统计分组查询
在MySQL中,只实现简单的分组查询有时候可能没有任何实际意义,因为关键字GROUP BY单独使用时,默认查询出每个分组中随机的一条记录,具有很大的不确定性,一般建议将分组关键字与统计函数一起使用。
如果想显示每个分组中的字段,可以通过函数GROUP_CONCAT()来实现。该函数可以实现显示每个分组中的指定字段,函数的具体语法形式如下:
SELECT GROUP_CONCAT(field)
FROM tablename
WHERE CONDITION GROUP BY field;
在上述语句中会显示每个数组中的字段值。
示例:使用GROUP_CONCAT()对班级进行统计分组,并显示每组中学生的姓名。
执行SQL语句GROUP_CONCAT(),显示每个分组,具体SQL语句如下:
mysql> create database school; #创建数据库school
mysql> use school; #选择数据库school
mysql> create table grade(id int UNIQUE AUTO_INCREMENT, name varchar(128) NOT NULL, math tinyint unsigned, chinese tinyint unsigned, english tinyint unsigned, class_id int NOT NULL); #创建成绩表 grade
mysql> insert into grade values(1, '甲', 80, 87, 91, 1),(2,'乙', 72, 64, 89,2),(3, '丙', 54, 69, 87,2),(4,'丁', 78, 79, 89, 1); #插入多条记录
mysql> SELECT GROUP_CONCAT(name) name, sum(math) FROM grade GROUP BY class_id; #按class_id 进行分组,统计数学总分并显示每个分组中的姓名
2 联合查询
2.1 内连接查询
在实际开发中,我们会联合多个表来实现查询,比如把班级表和学生表联合起来就同时可以看到班级、老师和学员的信息,一个班级表:

一个班级对应着多个学生,以下是与之对应的学生表”:

将两个表中ID 相同的记录关联起来组成一个新的“列表”,这就是联合查询:

这种只有2张表匹配的行才能显示的连接方式在Mysql 中称之为内连接: INNER JOIN。
在MySQL中内连接数据查询通过“INNER JOIN…ON”语句来实现,语法形式如下所示。
SELECT field1,field2,…,fieldn FROM tablename1
INNER JOIN tablename2 [INNER JOIN tablenamen] ON CONDITION
其中,参数fieldn表示要查询的字段名,来源于所连接的表tablename1和tablename2,关键字INNER JOIN表示表进行内连接,参数CONDITION表示进行匹配的条件。
举例如下:
mysql> create database school; #创建数据库school
mysql> use school; #选择数据库school
mysql> CREATE TABLE class (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(128) DEFAULT NULL,
`teacher` varchar(64) DEFAULT NULL,
UNIQUE KEY `id` (`id`)
); #创建班级表 class
mysql> insert into class values(101, '萌新一班', 'Martin'),(102, '萌新二班', 'Rock'),(103, '萌新三班', 'Janny'); #创建成绩表 grade
mysql> CREATE TABLE `student` (
`id` int NOT NULL AUTO_INCREMENT UNIQUE,
`name` varchar(64) DEFAULT NULL,
`class_id` int DEFAULT NULL,
`sex` enum('F','M') DEFAULT NULL
);
mysql> insert into student values(1,'小花',101,'M'),(2,'小红',102, 'F'),(3,'小军',102,'F'),(4,'小白',101,'F'); #插入多条记录
mysql> select * from class inner join student on class.id = student.class_id; #查询class 表和student 表中班级字段相同的记录并进行内连接
mysql> select * from class as a inner join student as b where a.id = b.class_id; #同上,使用别名查询
当表名特别长时,直接使用表名很不方便,或者在实现自连接操作时,直接使用表名无法区别表。为了解决这一类问题,MySQL提供了一种机制来为表取别名,具体语法如下:
SELECT field1, field2, ...,fieldn [AS] otherfieldn
FROM tablename1 [AS] othertablename1, ...,
Tablenamen [AS] othertablenamen ... where othertablename1.fieldx = othertablenamen.fieldx ... ;
其中,参数tablename为表原来的名字,参数othertablename为新表名,之所以要为表设置新的名字,是为了让SQL语句代码更加直观、更加人性化和实现更加复杂的功能。
自连接:
内连接查询中存在一种特殊的等值连接——自连接。所谓自连接,就是指表与其自身进行连接。
如:查询学生 ”小红 ”所在班级的其他学生,SQL语句如下:
mysql> use school; #选择数据库school
mysql> select t1.id, t1.name, t1.class_id from student t1 inner join student t2 on t1.class_id = t2.class_id and t2.name= '小红'; #查询学生 ”小红 ”所在班级的其他学生

等值连接:
内连接查询中的等值连接就是在关键字ON后的匹配条件中通过等于关系运算符(=)来实现等值条件。
mysql> select * from class as a inner join student as b where a.id = b.class_id;

不等值连接:
内连接查询中的不等连接就是在关键字ON后的匹配条件中通过除了等于关系运算符来实现不等条件外,还可以使用关系运算符,包含“>”“>=”“<”“<=”和“!=”等运算符号。
mysql> select * from class as a inner join student as b where a.id != b.class_id;

2.2 外连接查询
当我们在查询数据时,要求返回所操作表中至少一个表的所有数据记录,通过SQL语句“OUTER JOIN…ON”来实现。外连接数据查询语法形式如下:
SELECT field1,field2,…,fieldn
FROM tablename1 LEFT|RIGHT [OUTER] JOIN tablename2
ON CONDITION
在上述语句中,参数fieldn表示所要查询的字段名字,来源于所连接的表tablename1和tablename2,关键字OUTER JOIN表示表进行外连接,参数CONDITION表示进行匹配的条件。
外连接查询可以分为以下二类:
左外连接:
外连接查询中的左外连接,就是指新关系中执行匹配条件时,以关键字LEFT JOIN左边的表为参考表。左连接的结果包括LEFT OUTER字句中指定的左表的所有行,而不仅仅是连接列所匹配的行,如果左表的某行在右表中没有匹配行,则在相关联的结果行中,右表的所有选择列表均为空值。
例如:查询所有学生的学号、姓名、班级编号、性别、班级名、班主任信息,具体SQL语句如下:
mysql> use school; #选择数据库school
mysql> select * from student as a left join class as b on a.class_id = b.id; #左连接查询所有学生对应的班级信息
mysql> select * from class as a left join student as b on a.id = b.class_id; #左连接查询所有班级的学员信息

(左连接查询一 所有学员对应的班级信息)

(左连接查询二 所有班级对应的学员信息)
右外连接:
外连接查询中的右外连接在新关系中执行匹配条件时,以关键字RIGHT JOIN右边的表为参考表,如果右表的某行在左表中没有匹配行,左表将返回空值。
例如:查询所有班级的所有学生信息。具体SQL语句如下:
mysql> use school; #选择数据库school
mysql> select * from student as a right join class as b on a.class_id = b.id; #右连接查询所有班级对应的学员信息
mysql> select * from class as a right join student as b on a.id = b.class_id; #右连接查询所有学员对应的班级信息
2.3 合并查询数据记录
在MySQL中通过关键字UNION来实现合并操作,即可以通过其将多个SELECT语句的查询结果合并在一起,组成新的关系。在MySQL软件中,合并查询数据记录可通过SQL语句UNION来实现(字段数量必须相等),具体语法形式如下:
SELECT field1,field2,…,fieldn FROM tablename1
UNION | UNION ALL
SELECT field1,field2,…,fieldn FROM tablename2
UNION | UNION ALL SELECT field1,field2,…,fieldn ;
注意: 多个选择语句select 的列数相同就可以合并,union和union all的主要区别是union all是把结果集直接合并在一起,而union 是将union all后的结果再执行一次distinct,去除重复的记录后的结果。
mysql> use school; #选择数据库school
mysql> select teacher from class union all select name from student; #查询班级表所有老师和学生表中所有学生姓名
mysql> select teacher as people from class union all select name as people from student; #同上,使用别名查询
mysql> select teacher,id from class union all select name,class_id from student; #查询班级表所有(老师、班级ID)和学生表中所有学生(姓名、班级ID)

2.4 子查询
所谓子查询,是指在一个查询中嵌套了其他的若干查询,即在一个SELECT查询语句的WHERE或FROM子句中包含另一个SELECT查询语句。在查询语句中,外层SELECT查询语句称为主查询,WHERE子句中的SELECT查询语句被称为子查询,也被称为嵌套查询。
通过子查询可以实现多表查询,该查询语句中可能包含IN、ANY、ALL和EXISTS等关键字,除此之外还可能包含比较运算符。理论上,子查询可以出现在查询语句的任意位置,但是在实际开发中子查询经常出现在WHERE和FROM子句中。
带比较运算符的子查询:
子查询可以使用比较运算符。这些比较运算符包括=、!=、>、>=、<、<=和<>等。其中,<>与!=是等价的。比较运算符在子查询中使用得非常广泛,如查询分数、年龄、价格和收入等。
例如:查询student 表中“小花”所在班级班主任的名字。SQL语句如下:
mysql> use school; #选择数据库school
mysql> select teacher from class where id = (select class_id from student where name='小花'); #查询“小花”所在班级班主任的姓名
注意:使用比较运算符时,select 子句获得的记录数不能大于1条!!!
带关键字IN的子查询:
一个查询语句的条件可能落在另一个SELECT语句的查询结果中,这时可以使用IN关键字,SQL示例如下:
NOT IN的用法与IN相同。
例如:查询student 表中“小花”所在班级班主任的名字。SQL语句如下:
mysql> use school; #选择数据库school
mysql> select teacher from class where id in (select class_id from student where name='小花'); #查询student 表中“小花”所在班级班主任的名字
mysql> select teacher from class where id in (select class_id from student where name like '小%'); #查询姓名以“小”字开头的学生所在班级班主任的姓名
带关键字EXISTS的子查询:
关键字EXISTS表示存在,后面的参数是一个任意的子查询,系统对子查询进行运算以判断它是否返回行;如果至少返回一行,那么EXISTS的结果为true,此时外层语句将进行查询;如果子查询没有返回任何行,那么EXISTS返回的结果是false,此时外层语句将不进行查询。
例如:如果102班存在学生记录,就查询102班的班级信息的记录。SQL示例语句如下:
mysql> use school; #选择数据库school
mysql> select * from class where id=102 and exists (select * from student where class_id=102); #如果102班存在学生记录,就查询102班的班级信息
带关键字ANY的子查询:
关键字ANY表示满足其中任一条件。使用关键ANY时,只要满足内层查询语句返回的结果中的任何一个就可以通过该条件来执行外层查询语句。例如,需要查询哪些学生可以获取奖学金,那么首先要有一张奖学金表,从表中查询出各种奖学金要求的最低分,只要一个同学的乘积大于等于不同奖学金最低分的任何一个,这个同学就可以获得奖学金。关键字ANY通常和比较运算符一起使用。例如,“>ANY”表示大于任何一个值,“=ANY”表示等于任何一个值。
例如:查询数据库school的表student中哪些学生可以获得奖学金。学生的成绩达到其中任何一项奖学金规定的分数即可,SQL语句示例如下:
mysql> use school; #选择数据库school
mysql> create table scholarship (score int, level varchar(64));
mysql> insert into scholarship values(240, '二等奖'),(257,'一等奖');
mysql> select st.id, st.name, st.math+st.chinese+st.english total from grade st where (math+chinese+english) >= ANY (select score from scholarship); #查询能获得奖学金的学院记录
带关键字ALL的子查询:
关键字ALL表示满足所有条件。使用关键字ALL时,只有满足内层查询语句返回的所有结果才可以执行外层查询语句。例如,需要查询哪些同学能够获得一等奖学金,首先要从奖学金表中查询出各种奖学金要求的最低分。因为一等奖学金要求的分数最高,只有当成绩高于所有奖学金最低分时,这个同学才可能获得一等奖学金。关键字ALL也经常与比较运算符一起使用。例如,“>ALL”表示大于所有值,“<ALL”表示小于所有值。
例如:查询数据库school的表student中哪些学生可以获得一等奖学金,即学生的总成绩要达到一等奖学金规定的分数,而一等奖学金是最高奖学金。SQL语句示例如下:
mysql> use school; #选择数据库school
mysql> select st.id, st.name, st.math+st.chinese+st.english total from grade st where (math+chinese+english) >= ALL (select score from scholarship); #查询能获得一等奖学金的同学记录
mysql> select st.id, st.name, st.math+st.chinese+st.english total from grade st where (math+chinese+english) < ALL (select score from scholarship); #查询不能获得奖学金的同学记录
参考资料:
4万+

被折叠的 条评论
为什么被折叠?



