我有四个表格,其中包含以下结构: -
我正在尝试构建一个查询,该查询将输出出勤率低于他们所属课程的平均出勤率的出席。到目前为止我构建了两个查询
这将输出每门课程的与会者总数
这将输出每门课程的总数。
我认为我需要做的是将第一个查询的结果除以第二个查询的结果(这将给出每个课程的每个产品的平均出勤率),然后仅输出出勤率低于结果。我真的很难建立这个查询,所以我基本上寻找一些帮助
任何帮助都一如既往地受到赞赏
答案 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)