1.33.1 WHERE 嵌套子查询
功能描述
在WHERE子句中嵌套子查询,利用子查询的结果作为过滤条件。
语法格式
SELECT [ALL | DISTINCT] attr_expr_list FROM table_reference WHERE {col_name operator (sub_query) | [NOT] EXISTS sub_query};
关键字
● ALL:返回重复的行。为默认选项。其后只能跟*,否则会出错。
● DISTINCT:从结果集移除重复的行。
● WHERE:WHERE子句嵌套将利用子查询的结果作为过滤条件。
● operator:包含关系运算符中的等式与不等式操作符及IN,NOT IN,EXISTS,
NOT EXISTS操作符。
– 当operator为IN或者NOT IN时,子查询的返回结果必须是单列。
– 当operator为EXISTS或者NOT EXISTS时,子查询中一定要包含WHERE条件 过滤。当子查询中有字段与外部查询相同时,需要在该字段前加上表名。
注意事项
所要查询的表必须是已经存在的表,否则会出错。
示例
先通过子查询在course_info中找到Biology所对应的课程编号,再在student_info表中 找到选了该课程编号的学生姓名。
SELECT name FROM student_info
WHERE courseId = (SELECT courseId FROM course_info WHERE courseName = 'Biology');
1.33.2 FROM 子句嵌套子查询
功能描述
在FROM子句中嵌套子查询,子查询的结果作为中间过渡表,进而作为外部SELECT语 句的数据源。
语法格式
SELECT [ALL | DISTINCT] attr_expr_list FROM (sub_query) [alias];
关键字
● ALL:返回重复的行。为默认选项。其后只能跟*,否则会出错。
● DISTINCT:从结果集移除重复的行。
注意事项
● 所要查询的表必须是已经存在的表,否则会出错。
● FROM嵌套子查询中,子查询必须要取别名,且别名的命名要早于别名的使用,
否则会出错。建议别名不要重名。
● FROM后所跟的子查询结果必须带上前面所取的别名,否则会出错。
示例
返回选了course_info表中课程的学生姓名,并利用DISTINCT关键字进行去重。
SELECT DISTINCT name FROM (SELECT name FROM student_info JOIN course_info ON student_info.courseId = course_info.courseId) temp;
1.33.3 HAVING 子句嵌套子查询
功能描述
在HAVING子句中嵌套子查询,子查询结果将作为HAVING子句的一部分。
语法格式
SELECT [ALL | DISTINCT] attr_expr_list FROM table_reference GROUP BY groupby_expression
HAVING aggregate_func(col_name) operator (sub_query);
关键字
● ALL:返回重复的行。为默认选项。其后只能跟*,否则会出错。
● DISTINCT:从结果集移除重复的行。
● groupby_expression:可以是单字段,多字段,也可以是聚合函数,字符串函数 等。
● operator:此操作符包含等式操作符与不等式操作符,及IN,NOT IN操作符。
注意事项
● 所要查询的表必须是已经存在的表,否则会出错。
● 此处的sub_query与聚合函数的位置不能左右互换。
示例
对表student_info按字段name进行分组,计算每组中记录数,若其记录数等于子查询 中表course_info的记录数,返回表student_info中字段name等于表course_info字段 name的记录数。
SELECT name FROM student_info GROUP BY name
HAVING count(name) = (SELECT count(*) FROM course_info);
1.33.4 多层嵌套子查询
功能描述
多层嵌套子查询,即在子查询中嵌套子查询。
语法格式
SELECT attr_expr FROM ( SELECT attr_expr FROM ( SELECT attr_expr FROM... ... ) [alias] ) [alias];
关键字
● ALL:返回重复的行。为默认选项。其后只能跟*,否则会出错。
● DISTINCT:从结果集移除重复的行。
注意事项
● 所要查询的表必须是已经存在的表,否则会出错。
● 在嵌套查询中必须指定子查询的别名,否则会出错。
● 别名的命名必须在别名的使用之前,否则会出错,建议别名不要重名。
示例
通过三次子查询,最终返回user_info中的name字段。
SELECT name FROM ( SELECT name, acc_num FROM ( SELECT name, acc_num, password FROM ( SELECT name, acc_num, password, bank_acc FROM user_info) a ) b ) c;