计算每种奖励类型的平均值

时间:2019-03-10 23:38:14

标签: sql postgresql

对于每种奖励类型,我正在尝试计算该类型的奖励已包含在存款中的平均次数。对此的一个约束是,不包括奖励类型的存款不会为该类型的平均值贡献,而不是为0。

以下是架构:

rewards(rewardId, rewardType, rewardValue);
deposit(depositId, depositDate, customerId);
details(depositId, rewardsId, numDeposit);

这是我的查询:

select r.rewardsId, avg(dep.depositId) 
from deposit dep join details det 
    on dep.depositId = det.depositId join rewards r 
    on r.rewardsId = det.rewardsId  
group by r.rewardsId;

我得到的答案似乎不正确,因为平均水平很高,但是当我手动计算时,每种奖励类型我得到大约2。有人可以指出我做错了什么吗?

3 个答案:

答案 0 :(得分:0)

您绝对不希望获得id列的平均值。  那只是没有道理。

您可能只想count(*)

select r.rewardsId, count(*) as num_rewards 
from details det join
     rewards r 
     on r.rewardsId = det.rewardsId  
group by r.rewardsId;

据我所知,您不需要deposit表。存款ID在详细信息中。

或者,如果您希望每次存款获得奖励:

select r.rewardsId,
       count(*) * 1.0 / count(distinct det.depositId) as num_rewards 
from details det join
     rewards r 
     on r.rewardsId = det.rewardsId  
group by r.rewardsId;

答案 1 :(得分:0)

由于您只想计算包含奖励类型的存款,因此您可以像这样对它们进行计数:

select t.rewardsId, avg(t.counter) from (
  select 
    r.rewardsId, 
    sum(case when det.rewardsId is null then 0 else 1 end) counter
  from deposit dep join details det 
  on dep.depositId = det.depositId join rewards r 
  on r.rewardsId = det.rewardsId  
  group by r.rewardsId, dep.depositId
) t
group by t.rewardsId

答案 2 :(得分:0)

使用nullif(dep.depositId, 0)将零转换为null,这将不在平均计算中。

请考虑以下内容:

select  avg(val)            as avg_all, 
        avg(nullif(val, 0)) as avg_nonzero
from    (values
            (2), (4), (6), (0), (8), (0), (10)
        ) v(val) 

返回:

avg_all           |avg_nonzero       |
------------------|------------------|
4.2857142857142857|6.0000000000000000|

请参见nullif documentation