多表查询
之前学过在需要同时查询多个表时使用 JOIN 进行表关联,但其实还有一种方法,使用 WHERE 关键字进行表的关联。
WHERE 有等值与非等值连接。
语法:
SELECT 列名 ...
FROM 表名
WHERE [表名.]<列名1><比较运算符>[表名.]<列名2>;
比较运算符主要有:= 、> 、< 、>= 、<= 、!= 、<> 还有 and 和between 等
当连接运算符为=时为等值连接,其它的是非等值连接
eg1: where table1.c=table2.c(等值连接)
eg2: where table2.c>100 (非等值连接)
示例:
查询所有学生的各科成绩(学生ID,姓名,学科,成绩,班级)
SELECT a.id,a.name,c.subject_name,b.score,a.clazz
FROM
students AS a,
score AS b,
subject AS c
WHERE a.id = b.id AND
b.subject_id = c.subject_id;
WHERE 条件连接多表与 INNER JOIN 的效果是一样的。
子查询
对于多个表的同时查询,我们已经学过了 JOIN 关键字对多个表进行关联,学了 使用WHERE 条件连接多表,除此之外,其实还有一种办法,那就是子查询,也就是嵌套在查询中的查询。
子查询是SQL 语言的一种高级用法,我们知道,在SQL中,一个 SELECT-FROM-WHERE 语句称为一个查询块。当获得一个查询的答案需要多个步骤的操作,我们就可以根据步骤每一步写出一个查询块,再根据各个查询块之间的关系将它们嵌套在一起。 这样一来,等于是按照我们自己的想法来编写SQL语句,便于理解,提高可读性。
子查询一般可以分为三类:
SELECT 子查询
WHERE 子查询
FROM 子查询
我们接下来分别研究一下这三种子查询
SELECT 子查询
SELECT 子查询就是子查询块嵌套在另一个查询的 SELECT 语句中
我们给出一个题设,查询施笑槐同学六科成绩中的最高成绩
看到这个题目时,首先分析需要哪些表,查询的依据是姓名 施笑槐 ,那就需要 name 字段,只有 students 表有 name 字段,其次要查询成绩,也就是 score 字段,那就需要 score表。
然后我们设计查询思路,students 表与score 表的唯一关联之处在于 id 字段,所以我们可以在 students 表中用 name 字段查询出其对应 id,再使用 id 在score 表中查询其对应所有score 字段,然后使用 MAX 函数即可取出最大值。
有了思路我们便可以一步一步完成。先完成第一步,在 students 表中用 name 字段查询出其对应 id:
SELECT id
FROM students
WHERE name = '施笑槐';
接下来完成第二步,使用 id 在score 表中查询其对应所有score 字段,这里很明显,要使用的 id 就是我们第一步查询出来的结果中的 id 值,所以将这一步的查询块嵌套到上一步的 SELECT 语句中:
SELECT (SELECT score FROM score WHERE score.id = students.id) AS 最高成绩
FROM students
WHERE name = '施笑槐';
在这里,这个 students.id 其实就是在第一步中查询出来的 id 值,因为第一步的查询结果是 单行单列,也就是单个值,id 在第一步时被赋值,传递到子查询中进行。结果:
这里出现了报错,报错信息为 Subquery returns more than 1 row ,意思是**“子查询返回多于一行”,原因是每个学生id 在score表中有多行 score 数据**,而 SELECT 子查询不能返回多行结果,故而报错:
所以这里一般和聚合函数搭配使用,例如:
SELECT (SELECT MAX(score) FROM score WHERE score.id = students.id) AS 最高成绩
FROM students
WHERE name = '施笑槐';
通过子查询,我们便可以更加方便地实现多种多样的查询了,例如:
查询施笑槐同学的 id,姓名,总成绩和班级:
SELECT id,
name,
(SELECT SUM(score) FROM score WHERE score.id = students.id) AS 总成绩,
clazz
FROM students
WHERE name = '施笑槐';
查询文科三班所有同学的 id,姓名,总成绩和班级,并按总成绩进行降序排序:
SELECT id,
name,
(SELECT SUM(score) FROM score WHERE score.id = students.id) AS 总成绩,
clazz
FROM students
WHERE clazz = '文科三班'
ORDER BY 总成绩 DESC;
本专栏将持续更新,对数据库SQL感兴趣的同学可以关注一下,谢谢!