日期:2014-05-17  浏览次数:20809 次

求SQL查询代码纠正
本帖最后由 gridrender 于 2012-12-17 13:21:26 编辑

select sno from sc x where x.cno in (select cno from sc where sno='103' )
group by x.sno having count(x.cno)=(select count(cno) from sc where sno='103')


说明:SC是一个学生选课数据表,sno是学生学号,cno是课程编号,上述SQL语句的目标功能是“查询与103号学生选修的课程完全相同的其他学生的学号,即选修课程名称和选修的课程总数均相同”

问题:
(1)103号学生选修的课程是“数据库原理”和“高等数学”两门课程,但是上述代码可以检索到选修了“数据库原理”、“高等数学”和“离散数学”三门课程的106号学生。
(2)为啥上述代码执行之后,多了包含103号学生选修的全部课程,但选修的门数比103号学生多的学生106号。导致上述问题的原因是什么?如何修改?


select x.sno,sname from sc x,s
where s.sno=x.sno 
group by x.sno,s.sname having count(x.cno)=(select count(cno) from sc where sno='103')
intersect
select x.sno,s.sname from sc x,s
where s.sno=x.sno and x.cno in (select cno from sc where sno='103' )
group by x.sno,s.sname having count(x.cno)=(select count(cno) from sc where sno='103')

执行上述SQL代码才是我想要的查询结果,为啥呢?

------解决方案--------------------
select sno from sc x where x.cno in (select cno from sc where sno='103' ) group by x.sno having count(x.cno)=(select count(cno) from sc where sno='103')



where x.cno in (select cno from sc where sno='103' )这个部分假设查出来是100,101
由于你假了这个where限制,,所以select sno from sc x where x.cno in (select cno from sc where sno='103' ) 这个查出来永远是2条数据,刚好你的106也符合。然后再在这个查询结果基础上group by  。。count。怎么count(x.cno)都会是2条






------解决方案--------------------
#4已经解释的很清楚啦,因为你在where加了对课程的限制,所以对于106号学生来说,虽然他选了3门课,但是在这个where查询结果集里面只会返回两条,因为另一条课程记录是不满足你的where条件的。以此为基础的count当然是错误的。
不信你试试新建一个学生,让这个学生选着4,5甚至更多的课程,只要包含103的那两门课程,那么用第一条sql也会将这位新学生错误的查询出来。