2016-08-19 65 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