ORACLE AVG功能查询

时间:2013-04-09 16:14:48

标签: sql oracle average

我有四个表格,其中包含以下结构: -

我正在尝试构建一个查询,该查询将输出出勤率低于他们所属课程的平均出勤率的出席。到目前为止我构建了两个查询

这将输出每门课程的与会者总数

这将输出每门课程的总数。

我认为我需要做的是将第一个查询的结果除以第二个查询的结果(这将给出每个课程的每个产品的平均出勤率),然后仅输出出勤率低于结果。我真的很难建立这个查询,所以我基本上寻找一些帮助

任何帮助都一如既往地受到赞赏

1 个答案:

答案 0 :(得分:1)

一种方法是首先找到每个产品的参与者数量,然后从这个结果中找到每个课程的平均出勤率,加入每个相关产品的平均出勤率,然后选择实际出勤率的那些比平均水平更爱。

这可以使用CTE完成:

WITH attendee_counts AS
(SELECT c.course_id, o.offering_id,
        COUNT (Student_id) AS attendees     -- find attendance
 FROM course c
 INNER JOIN offering o 
 ON o.course_id = c.course_id
 LEFT JOIN attendance a
 ON a.offering_id = o.offering_id
 GROUP BY c.course_id, o.offering_id)       -- for each offering 

SELECT ac.course_id, ac.offering_id,
       ac.attendees, avgs.avg_attendees
FROM attendee_counts AS ac
INNER JOIN
 (SELECT course_id, AVG(attendees) AS avg_attendees   -- then average
  FROM attendee_counts
  GROUP BY course_id) AS avgs                         -- by course
ON avgs.course_id = ac.course_id
WHERE ac.attendees < avgs.avg_attendees;  

可以在此处测试查询(在PostgreSQL中有效):http://www.sqlfiddle.com/#!1/f5b60/20/0

修改

Oracle似乎需要稍微不同的解决方案:

WITH attendee_counts AS
(SELECT c.course_id, o.offering_id,
        COUNT (Student_id) AS attendees
 FROM course c
 INNER JOIN offering o  ON o.course_id  = c.course_id
 LEFT JOIN attendance a ON a.offering_id = o.offering_id
 GROUP BY c.course_id, o.offering_id)

SELECT o.course_id, o.offering_id, o.attendees,
  avg(c.attendees) AS avg_attendees
  FROM attendee_counts o              -- connect attendance by offering
LEFT JOIN attendee_counts c
ON c.course_id = o.course_id          -- to each offering of the same course
GROUP BY o.course_id, o.offering_id, o.attendees
HAVING o.attendees < avg(c.attendees);

这可以在这里测试http://www.sqlfiddle.com/#!4/e50e4/4/0(适用于Oracle 11g R2)