对团体进行锻炼

时间:2017-05-09 13:55:19

标签: sql oracle subquery oracle-sqldeveloper

我有以下数据库:

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;`

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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;