子查询(Sub Query)或者说内查询(Inner Query),也可以称作嵌套查询(Nested Query),是一种嵌套在其他 SQL 查询的 WHERE 子句中的查询。
子查询用于为主查询返回其所需数据,或者对检索数据进行进一步的限制。
子查询可以在 SELECT、INSERT、UPDATE 和 DELETE 语句中,同 =、<、>、>=、<=、IN、BETWEEN 等运算符一起使用。
使用子查询必须遵循以下几个规则:
子查询必须括在圆括号中。
子查询的
SELECT子句中只能有一个列,除非主查询中有多个列,用于与子查询选中的列相比较。子查询不能使用
ORDER BY,不过主查询可以。在子查询中,GROUP BY可以起到同ORDER BY相同的作用。返回多行数据的子查询只能同多值操作符一起使用,比如
IN操作符。SELECT列表中不能包含任何对BLOB、ARRAY、CLOB或者NCLOB类型值的引用。子查询不能直接用在聚合函数中。
BETWEEN操作符不能同子查询一起使用,但是BETWEEN操作符可以用在子查询中。
下面我们来看使用子查询的实例。
有 students 和 marks 两张表,分别如下。
students 表:
| id | name |
|---|---|
| 1 | Thomas |
| 2 | Dixon |
| 3 | Navarro |
| 4 | Cole |
marks 表:
| id | student_id | total_marks |
|---|---|---|
| 1 | 1 | 95 |
| 2 | 2 | 80 |
| 3 | 3 | 74 |
| 4 | 4 | 81 |
现在我们想写一个查询,以确定所有获得比学号(即:ID)为 2 的学生更高分数的学生,为了解决这个问题,我们需要两个查询。一个查询返回学号为 2 的学生分数,第二个查询将根据第一个查询的结果找出分数更高的学生。
很容易地我们写出第一个查询:
SELECT *
FROM marks
WHERE id = 2;
得到的结果是:
| id | student_id | total_marks |
|---|---|---|
| 2 | 2 | 80 |
现在我们知道了学号为 2 的学生成绩为 80,就可以写第二个查询来找出成绩比 80 高的学生。
SELECT students.id, students.name, marks.total_marks
FROM students, marks
WHERE students.id = marks.student_id
AND marks.total_marks > 80;
得到的结果是:
| id | name | total_marks |
|---|---|---|
| 1 | Thomas | 95 |
| 4 | Cole | 81 |
现在我们用子查询的方法,把上面两个查询合并到一起进行。
SELECT students.id, students.name, marks.total_marks
FROM students, marks
WHERE students.id = marks.student_id
AND marks.total_marks >
(SELECT total_marks
FROM marks
WHERE id = 2);
