2017-08-09 85 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和媒体如何根据不同类型的日常负载运行 –