前面刚分析过了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后都是一个表,这个表里存放着主体数据,需要的参数可以从其他表中获得,这个参数就需要子查询完成。