3

这是我的桌子

 Student (sname, sid, gpa, level, deptno) 
 Course (cno, cname, deptno, units) 
 Dept (dname, deptno) 
 Takes (sid, cno) 

编写一个 SQL 查询,返回在系外上过的课程比在系内上过更多课程的学生的姓名(即 snames)。您可以假设数据库中的所有学生至少在系内上过一门课程。

我不是在为这个问题寻找任何解决方案,但仍然欢迎任何答案。但我更希望人们能告诉我如何生成编写这样一个复杂查询的步骤..

我的回答是

 Select S.sname
 From Student S, Course C, Dept D, Takes T
 Where T.cno=C.cno and D.deptno=C.deptno and S.sid = T.sid
 Having COUNT(S.deptno=C.deptno) > COUNT( S.deptno != C.deptno)

我不确定我是否可以以这种方式使用 HAVING 后的计数。谢谢

4

3 回答 3

2

尽管从未上过 DB / SQL 课程,但我经常处理中等复杂的 SQL 查询,并且发现生成查询的最佳方法是一次处理一个。例如,首先要获取学生名单。然后,他们在部门内外采取的类数,最后,比较查询中的两个值并返回您需要的最终结果集。,

tl;博士:婴儿步骤

于 2012-10-31T20:02:34.507 回答
2

有人认为这是硬件,但这是标准解决方案:

 SELECT S.sname from Student S
 WHERE (SELECT COUNT (*) 
 FROM Takes T, Course C
 WHERE S.sid = T.sid AND T.cno = C.cno AND C.deptno = S.deptno)
 < (SELECT COUNT(*)
 FROM Takes T2, Course C2
 WHERE S.sid = T2.sid AND T2.cno = C2.cno AND C2.deptno != S.deptno)
于 2012-10-31T20:08:46.870 回答
1

您的第一次尝试,更正:

 SELECT S.sname
 FROM Student S, Course C, Dept D, Takes T
 WHERE T.cno = C.cno AND D.deptno = C.deptno AND S.sid = T.sid
 GROUP BY S.sid
 HAVING COUNT(CASE WHEN S.deptno =  C.deptno THEN 1 ELSE NULL END) 
      < COUNT(CASE WHEN S.deptno <> C.deptno THEN 1 ELSE NULL END) ;

并转换为 SQL-92 语法:

 SELECT S.sname
 FROM Student S 
   JOIN Takes T   ON S.sid = T.sid
   JOIN Course C  ON T.cno = C.cno
   JOIN Dept D    ON D.deptno = C.deptno
 GROUP BY S.sid        
        , S.sname                  --- this is not needed in SQL-2003
                                   --- but still required by most DBMS     
 HAVING 
        COUNT(CASE WHEN S.deptno =  C.deptno THEN 1 END) 
      < COUNT(CASE WHEN S.deptno <> C.deptno THEN 1 END) ;

                                   --- the ELSE NULL is not needed either
                                   --- it's the implied default
于 2012-10-31T20:17:27.093 回答