我有两张桌子,我试图按年份计算学生互动的数量,然后在各自的年份加总。我附加的代码有效,但我想知道我是否忽略了更简单的计算方法。例如,如果我想这样做超过2年,我会诅咒自己这样做。
select s.id
, coalesce(cl2016.cl2016, 0) + coalesce(wf2016.wf2016, 0) as s2016
, coalesce(cl2017.cl2017, 0) + coalesce(wf2017.wf2017, 0) as s2017
from students s
left join (
select dm.student_id
, count(dm.meeting_id) as cl2016
from dim_meetings dm
where dm.start_time between '2016-01-01' and '2016-12-31'
group by dm.student_id
) cl2016 on cl2016.student_id = s.id
left join (
select dm.student_id
, count(dm.meeting_id) as cl2017
from dim_meetings dm
where dm.start_time between '2017-01-01' and '2017-12-31'
group by dm.student_id
) cl2017 on cl2017.student_id = s.id
left join (
select sub.student_id
, count(sub.id) as wf2016
from submissions sub
where sub.submitted_at between '2016-01-01' and '2016-12-31'
group by sub.student_id
) wf2016 on wf2016.student_id = s.id
left join (
select sub.student_id
, count(sub.id) as wf2017
from submissions sub
where sub.submitted_at between '2017-01-01' and '2017-12-31'
group by sub.student_id
) wf2017 on wf2017.student_id = s.id
答案 0 :(得分:0)
使用条件聚合:
select s.id, dm.cl2016, cl2017, su.wf2016, su.wf2017,
coalesce(dm.cl2016, 0) + coalesce(su.wf2016, 0) as s2016,
coalesce(dm.cl2017, 0) + coalesce(su.wf2017, 0) as s2017
from students s left join
(select dm.student_id,
sum( (dm.start_time between '2016-01-01' and '2016-12-31')::int) as cl2016,
sum( (dm.start_time between '2017-01-01' and '2017-12-31')::int) as cl2017
from dim_meetings dm
where dm.start_time between '2016-01-01' and '2017-12-31'
group by dm.student_id
) dm
on dm.student_id = s.id left join
(select su.student_id,
sum( (su.start_time between '2016-01-01' and '2016-12-31')::int) as wf2016,
sum( (su.start_time between '2017-01-01' and '2017-12-31')::int) as wf2017
from submissions su
where su.start_time between '2016-01-01' and '2017-12-31'
group by su.student_id
) su
on su.student_id = s.id ;
答案 1 :(得分:0)
将case expression
置于聚合函数中非常有用,如下例所示:
select
dm.student_id
, count(dm.start_time '2016-01-01'
and < dm.start_time '2017-01-01' then dm.meeting_id end) as cl2016
, count(dm.start_time '2017-01-01'
and < dm.start_time '2018-01-01' then dm.meeting_id end) as cl2017
from dim_meetings dm
where dm.start_time between '2016-01-01' and dm.start_time < '2018-01-01'
group by dm.student_id
;
case expression
返回一个值,然后该值在聚合函数中使用,就像在任何其他值中一样。
请注意&#34;&#34;对于日期范围来说是邪恶的,而是通过>=
和<
使用显式范围,如上所示,其中包括将上边界日期向上移动到the next day
。参见: