SQL 知识量:22 - 44 - 129
子查询就是嵌套在其他查询中的查询。
例如:有一个学生表(student)和选课表(course),学生表中包含学生的基本信息,如下所示:
+----+--------+-----+--------+ | id | name | age | sex | +----+--------+-----+--------+ | 1 | Susan | 11 | female | | 2 | Jame | 12 | male | | 3 | Bob | 11 | male | | 4 | Robot | 10 | male | | 5 | Jen | 11 | female | | 6 | Toney | 10 | male | | 7 | Jack | 13 | male | | 8 | Alice | 10 | female | | 9 | Bonnie | 11 | male | | 10 | Ella | 12 | female | +----+--------+-----+--------+
选课表中包含选课的学生id和选择的课程id,如下所示:
+----+------------+-----------+ | id | id_student | id_lesson | +----+------------+-----------+ | 1 | 1 | 1 | | 2 | 5 | 3 | | 3 | 2 | 1 | | 4 | 4 | 1 | | 5 | 6 | 1 | | 6 | 1 | 2 | | 7 | 3 | 2 | | 8 | 4 | 2 | | 9 | 5 | 2 | | 10 | 2 | 3 | | 11 | 4 | 3 | | 12 | 6 | 3 | +----+------------+-----------+
现在,查询所有选了课的学生姓名。一般的思路是:
先在选课表中查询出选课学生的id。
再在学生表中查询出id与选课学生id相同的学生信息。
利用子查询进行操作的SQL语句为:
select name from student where id in (select distinct id_student from course);
结果:
+-------+ | name | +-------+ | Susan | | Jame | | Bob | | Robot | | Jen | | Toney | +-------+
由上面的SQL语句可知,在子查询时,第一步查询作为子查询放置于第二步查询的in操作符后面。在SQL运行时,DBMS总是先运行内层子查询,再运行外层查询。
需要注意的是:
作为子查询的select语句只能查询单个列。
嵌套的子查询越多,数据库性能下降越厉害,因此,尽可能减少嵌套。
使用子查询的另一种方法是创建计算字段。
例如查询学生姓名和已选课程的数量,按照学生姓名排序。这涉及两个表:学生表(student)和选课表(course),SQL语句为:
select name, (select count(*) from course where course.id_student=student.id) as course_selected from student order by name;
结果:
+--------+-----------------+ | name | course_selected | +--------+-----------------+ | Alice | 0 | | Bob | 1 | | Bonnie | 0 | | Ella | 0 | | Jack | 0 | | Jame | 2 | | Jen | 2 | | Robot | 3 | | Susan | 2 | | Toney | 2 | +--------+-----------------+
以上语句的关键是子查询的where子句中的course.id_student=student.id,表示这里要比较一下course中的id_student与student中的id是否一致。如果没有这一过滤条件,结果会是一个笛卡尔积,这当然不是正确答案。
在使用多个表时,如果表中的列名相似、容易混淆,则必须使用完全限定列名,具体方法是在列名前加上表的名字,并用点(.)联结列名。
Copyright © 2017-Now pnotes.cn. All Rights Reserved.
编程学习笔记 保留所有权利
MARK:3.0.0.20240214.P35
From 2017.2.6