按星期几分组中位数

时间:2016-08-20 17:17:33

标签: sql postgresql

我试图按工作日对会话的中间响应时间进行分组

这是我到目前为止所得到的,但它没有正确分组(每个app_id有多个条目,每个条目都有自己的响应时间值。相反,这些条目应分组为一个,只显示中值)

有什么想法吗?

select
    c.app_id,
    case when extract(dow from c.first_response_at) = 1 then percentile_cont(0.5) within group ( order by c.response) else 0 end as mon,
    case when extract(dow from c.first_response_at) = 2 then percentile_cont(0.5) within group ( order by c.response) else 0 end as tue,
    case when extract(dow from c.first_response_at) = 3 then percentile_cont(0.5) within group ( order by c.response) else 0 end as wed,
    case when extract(dow from c.first_response_at) = 4 then percentile_cont(0.5) within group ( order by c.response) else 0 end as thu,
    case when extract(dow from c.first_response_at) = 5 then percentile_cont(0.5) within group ( order by c.response) else 0 end as fri,
    case when extract(dow from c.first_response_at) = 6 then percentile_cont(0.5) within group ( order by c.response) else 0 end as sat,
    case when extract(dow from c.first_response_at) = 7 then percentile_cont(0.5) within group ( order by c.response) else 0 end as sun
from
(
with t(app_id, response, first_response_at, updated_at) as (
    select app_id, extract(epoch from (first_response_at - started_at)) as response_time, first_response_at, c.updated_at
    from apps a
    left join conversations c on c.app_id = a.id
    order by c.updated_at desc
)
select app_id, response, first_response_at, updated_at
from t
) as c
group by c.app_id, c.first_response_at, c.updated_at
order by c.updated_at desc

2 个答案:

答案 0 :(得分:1)

#1:您需要按照Gordon Linoff的建议将CASE移至PERCENTILE_CONT

#2:从, c.first_response_at, c.updated_at

中删除group by

#3:按minmax(c.updated_at)

排序

#4:不需要嵌套的CTE / Order By

#5:将Extract(dow)移到Deried Table

select
    c.app_id,
    PERCENTILE_CONT(0.5) WITHIN GROUP ( ORDER BY CASE WHEN dow = 1 THEN c.response end) as mon,
    PERCENTILE_CONT(0.5) WITHIN GROUP ( ORDER BY CASE WHEN dow = 2 THEN c.response end) as tue,
    PERCENTILE_CONT(0.5) WITHIN GROUP ( ORDER BY CASE WHEN dow = 3 THEN c.response end) as wed,
    PERCENTILE_CONT(0.5) WITHIN GROUP ( ORDER BY CASE WHEN dow = 4 THEN c.response end) as thu,
    PERCENTILE_CONT(0.5) WITHIN GROUP ( ORDER BY CASE WHEN dow = 5 THEN c.response end) as fri,
    PERCENTILE_CONT(0.5) WITHIN GROUP ( ORDER BY CASE WHEN dow = 6 THEN c.response end) as sat,
    PERCENTILE_CONT(0.5) WITHIN GROUP ( ORDER BY CASE WHEN dow = 7 THEN c.response end) as sun
from
 (
   select app_id,
       extract(epoch from (first_response_at - started_at)) as response_time, 
       EXTRACT(dow FROM c.first_response_at) as dow,
       c.updated_at
   from apps a
   left join conversations c on c.app_id = a.id
 ) as c
group by c.app_id
order by max(c.updated_at) desc

答案 1 :(得分:0)

percentile_cont()应忽略NULL个值。因此,您希望将内部的日期条件移动到函数调用中:

with t(app_id, response, first_response_at, updated_at) as (
       select app_id, extract(epoch from (first_response_at - started_at)) as response_time, first_response_at, c.updated_at
       from apps a left join
            conversations c
            on c.app_id = a.id
      )
select c.app_id,
       percentile_cont(0.5) within group
           (order by (case when extract(dow from c.first_response_at) = 1 then c.response end)) as mon,
       . . .
from t
group by c.app_id, c.first_response_at, c.updated_at
order by c.updated_at desc;

编辑:

嗯,我应该上面的工作。但是,filter可能更合适:

select c.app_id,
       percentile_cont(0.5) within group (order by c.response)
           filter (where extract(dow from c.first_response_at) = 1) as mon,
. . .