1.子查询
将一条select语句返回的结果用于另一条select语句的where子句中。
执行时,先执行子查询,再执行主查询。
select sid
from sc
where cid in (select cid
from course
where cname='数据库应用技术');
子查询一般与 IN 操作符结合使用,也可以用来测试等于(=), 不等于(!=)。
通过增加子查询来建立查询。随着语句的复杂性增加,子查询用来测试和调试查询更加方便,最可靠的方法是逐渐进行,首先建立外层查询,并且在确认其正确后再嵌入子查询,逐步确认嵌入子查询后的准确性。这为后面找出查询bug节省的很多时间。
2.联结
数据存储在多张表中,如何使用一条select语句检索?答案是使用联结(join)。
/* student(sid,sname,sex..)
sc(sid,cid,grade)
查询选修了16020011号课程并且成绩在80以上的学生姓名 */
select sname
from student,sc
where student.sid = sc.sid
and cid = '16020011'
and grade > 80;
完全限定列名:如 student.sid , sc.sid ,当多张表中有相同列名时,需要一个点分隔表名和列名。
笛卡尔积:第一个表中的每个行将与第二个表中的每个行配对,而不管它们逻辑上是否可以配在一起。没有联结条件的表关系返回的结果为笛卡尔积。检索出的数目是两个表的行数乘积。
以上称为等值联结,同时也叫做内部联结,它的返回结果是一样,但语法上稍微不同,以 …inner join…on…
上述查询用内部联结写法:
select sname
from student inner join sc
on student.sid = sc.sid
and cid='16020011'
and grade > 80;
3.高级联结
3.1 自联结
3.2外联结
多个表联结时,有时需要包含那些没有关联行的那些行。例如,查询所有课程的选修人的学号,其中有些课程可能没有学生选择,如果使用等值连接,那么那些没有被选的课程不会出现在检索结果中,这时候需要使用外联结来保留课程表的所有行。
left outer join:选中左边表的所有行
right outer join:选中右边表的所有行
course表
sc表
#使用等值连接
select sid, course.cid
from course, sc
where course.cid = sc.cid;
课程表中没有被选的课不会出现
#使用外连接
select sid, course.cid
from course left outer join sc
on course.cid = sc.cid;
保留了所有课程号,没有与其相关联的行值用null显示。