2016-08-19 113 views
0

我想要聚合表中的每个应用统计apps汇总列返回零

我有以下查询,但由于某些原因,所有的结果返回0

select 
    a.id, 
    'support' as domain, 
    'summary' as type, 
    90 as interval, 
    json_build_object(
     'new', count(new), 
     'closed', count(closed_c), 
     'reply_rate', count(reply_rate), 
     'median_response', max(median_response.response_time) 
    ) as data 
from apps a 
full join (
    SELECT * from conversations c 
    WHERE c.started_at::date > (current_date - (90 || ' days')::interval)::date 
) as new on new.app_id = a.id 
full join (
    SELECT * from conversations c 
    WHERE c.closed_at::date > (current_date - (90 || ' days')::interval)::date 
) as closed_c on closed_c.app_id = a.id 
full join (
    SELECT * from conversations c 
    WHERE c.started_at::date > (current_date - (90 || ' days')::interval)::date AND c.first_response_at is not null 
) as reply_rate on reply_rate.app_id = a.id 
full join (
    SELECT c.app_id, extract(epoch from (c.first_response_at - c.started_at)) as response_time, ntile(2) OVER (ORDER BY (c.first_response_at - c.started_at)) AS bucket FROM conversations c 
    WHERE c.started_at::date > (current_date - (90 || ' days')::interval)::date AND c.first_response_at is not null 
) as median_response on median_response.app_id = a.id 
where a.test = false 
group by a.id 
+0

'max(median_response.response_time)'也返回0吗?你是否获得了'a.id'的值?你会得到子查询记录吗?他们是否正确加入?这些聚合是否在'json_build_object()'之外工作?如果你改变为'Count(new。*)'而不是'Count(new)'? – JNevill

+0

那个返回'null'。我正在获取'a.id'的值。子查询应该返回记录?他们在外面工作。不改变任何东西 – Tarlen

+0

聚合公式在'json_build_object()'之外工作吗?这真的让事情变窄了! – JNevill

回答

1

我不能告诉到底为什么一切都是零,但

#1:full joinleft join更换(因where a.test = false

#2:当你与不同的条件访问同一个表四倍这可以或许通过一个单一的选择使用条件的聚集所取代。

检查这个返回正确的计数,然后离开它加入到apps

select 
    app_id, 
    sum(new), 
    sum(closed_c), 
    sum(reply_rate), 
    max(case when bucket = 1 then response_time end) 
from 
(
    SELECT app_id, 

     1 as new, 

     case when c.closed_at::date > (current_date - (90 || ' days')::interval)::date then 1 else 0 end as closed_c, 

     case when c.first_response_at is not null then 1 else 0 end as reply_rate, 

     extract(epoch from (c.first_response_at - c.started_at)) as response_time, 

     ntile(2) OVER (ORDER BY (c.first_response_at - c.started_at)) AS bucket 
    FROM conversations c 
    -- assuming that closed_at is always after started_at 
    WHERE c.started_at::date > (current_date - (90 || ' days')::interval)::date 
) as dt 
group by app_id 
+0

这几乎是正确的,唯一的问题是,它不返回'在过去90天内apps'不hvae任何启动对话。它应该返回应用程序ID为这些,但后来只是在总结 – Tarlen

+0

@Tarlen零:这就是为什么你需要'左join'为'apps'然后用'COALESCE(...,0)'来获得零。 – dnoeth

+0

我不确定我是否跟着你,你在上面没有使用任何连接? – Tarlen

0

你为什么这样做当你不使用这些表中的单个列时,有很多联接吗?

如果你只需要来算,你可以做这样的:

select 
    a.id, 
    'support' as domain, 
    'summary' as type, 
    90 as interval, 
    json_build_object(
     'new',    (SELECT count(*)              from conversations c WHERE c.app_id = a.id and c.started_at::date > current_date - 90), 
     'closed',   (SELECT count(*)              from conversations c WHERE c.app_id = a.id and c.closed_at::date > current_date - 90), 
     'reply_rate',  (SELECT count(*)              from conversations c WHERE c.app_id = a.id and c.started_at::date > current_date - 90 and c.first_response_at is not null), 
     'median_response', (SELECT max(extract(epoch from (c.first_response_at - c.started_at))) from conversations c WHERE c.app_id = a.id and c.started_at::date > current_date - 90 and c.first_response_at is not null) 
    ) as data 
from apps a 
where a.test = false 

另外,为什么您使用的间隔加/减天到date类型?你可以做current_date - 90

,我建议你在conversations创建一些指标也:

create index i_conversations_started_at on conversations (id, started_at::date); 
create index i_conversations_closed_at on conversations (id, closed_at::date); 
+0

虽然这看起来更干净,这是10倍左右的时间慢,而且还犯规解决问题与零个值 – Tarlen

+0

如果它是慢,你应该建立正确的索引。 – Christian

+0

0值有什么问题? – Christian