我有四个具有以下结构的表:-
我正在尝试构建一个查询,该查询将输出出勤率低于其所属课程的平均出勤率的课程。到目前为止,我已经构建了两个查询
这将输出每个课程的参加者总数
这会输出每门课程的课程总数。
我认为我需要做的是将第一个查询的结果除以第二个查询的结果(这将为我提供每门课程的每个课程的平均出勤率),然后仅输出出勤率低于该结果的课程。我真的很难建立这个查询所以我基本上是在寻找一些帮助
一如既往地感谢任何帮助
一种方法是首先找到每个课程的参加人数,然后从该结果中找到每门课程的平均参加人数,将平均参加人数加入每个相关课程,然后选择实际参加人数为情人的课程。平均值。
这可以使用 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)