2017-05-09 48 views
0

我有以下数据库:运动对群体

Prof(profBadge, profName, Department) Course(courseCod, courseName, profBadge, area) Class(classCode, date, courseCod, numberOfStudents)

并提出以下要求: 对于谁只在该地区的数据库课程显示工号和课程其中最高平均每位教授学生的。

Create view badgeList(profBadge, courseCod) as 
SELECT DISTINCT profBadge, courseCod 
FROM Coure 
WHERE (profBadge NOT IN (SELECT profBadge 
        FROM Course 
        WHERE Area <> 'database')); 

Create view avgLessons(AvgStud, courseCod) as 
SELECT AVG(numberOfStudents), courseCod 
FROM class 
GROUP BY courseCod; 

Create view MaxStudent(maxStu, profBadge) as 
select max(med.avgStud), el.profBadge 
from avgLessons med, badgeList el 
where med.courseCod= el.courseCod 
group by el.profBadge; 

select DISTINCT MS.profBadge, MS.MAXSTU, Corso.CODCORSO 
from MaxStudent MS, course, class 
where MS.profBadge = course.profBadge and MS.maxStu = class.numberOfStudents and course.courseCod = class.courseCod;` 
+3

将其分解成部分。首先,你如何找到平均学生人数最多的课程?那么你如何加入到数据集并显示“数据库”课程的徽章和课程编号? – xQbert

+0

但是,如果我找到最高编号的课程,我会失去其他课程的信息,或者不是?我需要为每位教授 –

+1

找到平均学生人数最多的课程,因此在该计算中包含一组在profbadge上的小组。并使用徽章和课程加入。我试图避免的是为你写答案,而是引导你尝试自己尝试解决问题的方法。那老人教导人们为了生活而吃鱼,让他们吃一天他们吃的鱼。不要吃整个大象,每次只吃一口,看看它是如何结合在一起的。分解为组成部分的复杂事物变得简单,当您将组件重新放回时,它不再复杂。 – xQbert

回答

0

我不知道如果我看到你想达到什么样的,但下面的代码返回profBadges只有那些courseNames其中有学生(通过属于类的数量计算)的最高平均数量。

SELECT profBadge, 
    courseName 
FROM 
    (SELECT C.profBadge, 
    C.courseName, 
    SUM(CL.numberOfStudents)              /COUNT(CL.classCode) AS Avg_Students_Num, 
    ROW_NUMBER() OVER (PARTITION BY C.profBadge ORDER BY SUM(CL.numberOfStudents)/COUNT(CL.classCode)) AS Rank 
    FROM Course C 
    LEFT JOIN Class CL 
    ON CL.courseCod=C.courseCod 
    GROUP BY C.courseName, 
    C.profBadge 
) 
WHERE Rank=1 
+0

只处理只有'数据库'区域的教授。 – xQbert

0

这并非易事。如前所述,请一步一步来做。

第1步:只有区域'数据库'的课程的教授。正如你所做的那样使用NOT IN是解决这个问题的一种方法。另一个(通常最快)是聚合。

SELECT profBadge 
FROM Course 
GROUP BY profBadge 
HAVING MIN(Area) = 'database' AND MAX(Area) = 'database'; 

第2步:每个课程的平均学生人数,如你所展示的。

SELECT courseCod, AVG(numberOfStudents) 
FROM class 
GROUP BY courseCod; 

第3步:将两者结合。您可以选择profBadge位于第一组(第1步中的查询)的课程,并按平均学生人数(您必须加入第2步中的查询)对其排名。

SELECT courseCod, courseName, profBadge, area 
FROM 
(
    SELECT 
    c.courseCod, c.courseName, c.profBadge, c.area, 
    RANK() OVER (PARTION BY c.profBadge ORDER BY av.avgNum DESC) AS rn 
    FROM Course c 
    JOIN 
    (
    SELECT courseCod, AVG(numberOfStudents) AS avgNum 
    FROM class 
    GROUP BY courseCod 
) av ON av.courseCod = c.courseCod 
    WHERE c.profBadge IN 
    (
    SELECT profBadge 
    FROM Course 
    GROUP BY profBadge 
    HAVING MIN(Area) = 'database' AND MAX(Area) = 'database' 
) 
) 
WHERE rn = 1;