前面刚分析过了SQL server高级连接查询:自连接、内连接、外连接,今天来解释一下子查询,SQL server中的子查询是指在SELECT语句中嵌入一个SELECT子句,这种查询方式可以将子查询中的一个结果作为参数进行二次查询,实际上整个过程中就已经查询了两次。
子查询分为两种:
1. 返回单值的子查询。
这种查询指嵌入的查询语句返回的是一个值,这个值作为外部SELECT语句的参数。
Select….from table1 where 字段=(select …from table2…)
子查询中嵌入的SELECT子句查询的表可以是外部语句中的表,也可以是数据库中其他表。如果是其他表,其实就实现了内查询中的功能,等值查询、自然查询、不等值查询,所以,返回单值的子查询可以使用关系运算符=,<,>,<>,!=等。
子查询和内查询的区别:子查询的子句是放在WHERE中通过一个关系运算符连接起来的SELECT表达式中;内查询是放在FROM后或者在WHERE后通过条件判断语句设定条件来实现的。
子查询可以和聚合函数结合使用,在WHERE中是不能直接使用聚合函数的,但是在子查询的内嵌select语句中是可以的,这样就能时间更大的功能。
举例:score(学号,课号,平时成绩,期末成绩)
Course(课号,课名)
题:查询“计算机”期末成绩大于“计算机”期末成绩平均分的所有学生的平时成绩和期末成绩。
Select 学号,平时成绩,期末成绩
From score
Where 课号=(select 课号 from course where 课名=’心理学’)
And 期末成绩> (select avg(期末成绩) from score where 课号=(select 课号 from course where 课名=’计算机’))
Order by 期末成绩 desc
第一个select:从score查询学号,平时成绩,期末成绩
第二个select:从course查询出课号 做第一个select参数
第三个select:从score中求平均值 做第一个select参数
第四个select:从course中查询课号 做第三个select参数
这里用了3个子查询。
2. 返回一列值的子查询。
这类子查询中select子句查询出来的值不是一个值,而是一列值,这时候外部select语句的关系运算符中就只有in和not in能做出判断了。
1. 使用in的子查询。
Select …from table1 where 字段 in(select .. from table2 where …)子查询中返回一类值
2. 使用not in的子查询。
和in是一个道理,只是条件反向。
相关子查询:这种查询是老式的方法,主查询提供数据作为子查询的参数,子查询查询的结果再作为主查询的参数,这样循环完成最后的操作:
举例:score(学号,课号,平时成绩,考试成绩)
Student(学号,姓名,性别,所属院系)
要求:查询出计算机系的所有学生的学号,姓名,考试总成绩
Select 学号,姓名,sum(select 考试成绩 from score as sc where sc.学号=st.学号) as 考试总成绩
From student as st
where 所属院系=’计算机’
Order by 考试总成绩
(1) 从student中查询出一行数据
(2) 将第一步中查询出的数据学号提供给子查询,从score中查询出考试成绩,计算一个学号的总成绩
(3) 将上一步查询出的总成绩存放到主查询的第一行记录中
(4) 继续1,2,3步骤,依次循环,直到查询出所有符合条件的数据。
这样实际上是一条一条的循环查询数据,得出结果
利用内查询就可以很方便的解决这个问题
解决方案利用内查询:
Select st.学号, st.姓名,sum(sc.考试成绩) as 考试总成绩
From student as st,score as sc
Where st.所属院系=’计算机’
And st.学号= sc.学号
Order by 考试总成绩 desc
这个查询不适合用子查询完成,因为姓名存放在一个表中,考试成绩存放在另一个表中,必须从两个表查询数据组合进起来,不仅仅是缺少参数。
SQL server中的子查询总结:子查询实际大多数数据都在一个表中,只是缺少部分从其他表中查询的参数,这时候适合使用子查询完全功能。FROM后都是一个表,这个表里存放着主体数据,需要的参数可以从其他表中获得,这个参数就需要子查询完成。