2017-08-09 82 views
3

我有有列的表稱爲工作:PostgreSQL的數據基於桶分析

CREATE TABLE work (user text, user_type text, medium text, 
docs_read int, on_date timestamp with timezone); 

我想創建每天閱讀的文件數量的桶(0-99,100-199等),計算每天user_type和medium的每種組合的平均,最小和最大生產力。

我可以on_date計算docs_read和組和使用,讓每一天docs_read數:

SELECT on_date::date as day, sum(docs_read) as total_docs_read 
FROM work GROUP BY day; 

現在,我不得不每天組total_docs_read成大小100桶,並計算平均值,最小值和每個用戶類型的生產力的最大值和每個桶的介質。

生產力=在用戶的日/數docs_read的和工作的那一天

基本上我們有不同類型的用戶喜歡的教授,助理教授等閱讀不同語言的文檔,並且我們想知道多少文檔他們每位用戶每天閱讀。因此,對於每個工作負荷桶,每個用戶類型和媒介,我希望獲得平均生產力的平均值,最大值和最小值,這些值是在桶內的多天內每天的平均生產力。

樣本輸出應該是:

docs_read_bucket user_type medium avg_prod max_prod min_prod 
0-99    A   English  30  50   15 

回答

1

讓我們分別定義分別對應於分組'0-99','100-199','200-299','300-399'...的桶索引0,1,2,3 ...。數學bucket_index = floor(total_docs_read/100)。

檢查下面的查詢是否適合您。

解決方案摘要 - 我們首先爲每個user_type和medium在每天的生產力創建一個表。我們每天爲total_docs_read創建另一個表。然後,我們在一天中加入這兩個表,並將結果表彙總到bucket_index,user_type和medium上。

SELECT 
    bucket_index, user_type, medium, AVG(productivity) as avg_prod, 
    MAX(productivity) as max_prod, MIN(productivity) as min_prod 
FROM 
    (SELECT 
      floor(t1.total_docs_read/100) as bucket_index, 
      t2.user_type as user_type, t2.medium as medium, 
      t2.productivity as productivity 
    FROM 
     (SELECT 
      on_date::date as day, sum(docs_read) as total_docs_read 
     FROM work 
     GROUP BY day) as t1, 
     (SELECT 
      on_date::date as day, user_type, medium, 
      sum(docs_read)/count(distinct(user)) as productivity 
     FROM work 
     GROUP BY day, user_type, medium) as t2 
    WHERE t1.day=t2.day) as t3 
GROUP BY bucket_index, user_type, medium 
+0

爲什麼使用此「sum(docs_read)/ count(distinct(user)) '而不是'AVG(docs_read)'?我認爲你的查詢更通用,但每個用戶每天只有一個條目。兩者都應該給出相同的答案? –

0

你要聚集的兩個層次。如果我理解正確的話,你想:

SELECT floor(total_docs_read/100) as grp, 
     day, user_type, medium, 
     AVG(total_docs_read) as avg_prod, 
     MAX(total_docs_read) as max_prod, 
     MIN(total_docs_read) as min_prod, 
FROM (SELECT user, user_type, medium, on_date::date as day, 
      sum(docs_read) as total_docs_read 
     FROM work 
     GROUP BY user, user_type, medium, day 
    ) w 
GROUP BY grp, day, user_type, medium 

我不是100%肯定這是你的「生產力」的定義相匹配。但是,這似乎是一個明智的結果。

+0

我已更新生產力的定義。請看一看。 –

+0

您的total_docs_read會在用戶,用戶類型,媒介和日期之間進行拆分。但是我希望小組根據當天的工作量。這將代表高工作日,中等或低工作日,然後我們可以看到不同的user_types和媒體如何根據不同類型的日常負載運行 –