2017-10-19 500 views
1

我有一个表movesPostgreSQL Group按类别,计数和计算百分比值

uuid | tag | ... 
-----| ----|---- 
abc | 520 | ... 
def | 510 | ... 
ghi | 500 | ... 
jkl | 310 | ... 
mno | 200 | ... 

tag代表移动的类型。我们正在谈论沙滩排球的动作。第一个号码,例如520中的5个是该类别。在这种情况下“服务”。在总我有六大类:

  1. 攻击(1类,如100110120
  2. 块(2类)
  3. 挖(3类)
  4. 接待(第4类)
  5. 服务(5类)
  6. 设定(6类)

最后的数字,即来自520的20,是结果。在这种情况下“赢”。每个类别有3个可能的结果:

  1. 错误(00
  2. 零(10
  3. 运(20

下面是从上表标签上方

  1. 520 - 服务赢(这是一个王牌)
  2. 510 - 服务零
  3. 500 - 服务错误
  4. 310 - 挖零
  5. 200 - 块错误

这里是想什么,我得到:给我的错误计数,零,以绝对值和相对值赢得每个类别。

我尝试以下

select *, 
    (attack_error::float/attacks::float * 100) as attack_error_percentage, 
    (attack_zero::float/attacks::float * 100) as attack_zero_percentage, 
    (attack_win::float/attacks::float * 100) as attack_win_percentage 
    from (
     select 
      count(*) filter (where tag = 100) as attack_error, 
      count(*) filter (where tag = 110) as attack_zero, 
      count(*) filter (where tag = 120) as attack_win, 
      count(*) filter (where tag = 100 or tag = 110 or tag = 120) as attacks 
     from moves 
     where match_uuid = 'd7eea231-a63d-4d73-b48f-5ca8541ec9cf' and set = 1 
    ) 
as attack_stats 

,并得到了这样的事情

att_error | att_zero | att_win | total | att_error_% | att_zero_% | att_win_% 
----------|----------|---------|-------|-------------|------------|---------- 
1   | 3  | 13  | 17 | 5.88  | 17.65  | 76.47 

但是它不觉得权利,我不得不一次又一次地重复查询所有不同类别与所有的结果。

我真的很想得到的是这样的。

category | error | zero | win | total | error_% | zero_% | win_% 
---------|-------|------|-----|-------|---------|--------|------ 
1  | 2  | 4 | 6 | 12 | 0.16 | 0.33 | 0.5 
2  | 3  | 8 | 13 | 24 | 0.125 | 0.33 | 0.54 
3  | ... | ... | ... | ... | ...  | ... | ... 
4  | ... | ... | ... | ... | ...  | ... | ... 
5  | ... | ... | ... | ... | ...  | ... | ... 
6  | ... | ... | ... | ... | ...  | ... | ... 

任何想法?

回答

1

考虑与CASE声明有条件创建类别列,包括其作为派生表汇总查询

select *, 
    (error::float/total::float * 100) as error_percentage, 
    (zero::float/total::float * 100) as zero_percentage, 
    (win::float/total::float * 100) as win_percentage 
    from (
     select 
      case substring(tag::text, 1, 1) 
       when '1' then 'Attack' 
       when '2' then 'Block' 
       when '3' then 'Dig' 
       when '4' then 'Reception' 
       when '5' then 'Service' 
       when '6' then 'Setting' 
      end as category, 
      count(*) filter (where tag - round(tag/100, 0)*100 = 0) as error, 
      count(*) filter (where tag - round(tag/100, 0)*100 = 10) as zero, 
      count(*) filter (where tag - round(tag/100, 0)*100 = 20) as win, 
      count(*) filter (where tag - round(tag/100, 0)*100 <= 20) as total 
     from moves 
     where match_uuid = 'd7eea231-a63d-4d73-b48f-5ca8541ec9cf' and set = 1 
     group by 
      case substring(tag::text, 1, 1) 
       when '1' then 'Attack' 
       when '2' then 'Block' 
       when '3' then 'Dig' 
       when '4' then 'Reception' 
       when '5' then 'Service' 
       when '6' then 'Setting' 
      end 
    ) 
as attack_stats 
+0

它种工作的GROUP BY。我得到了预期的表格布局,但只有Attack行有结果。所有其他行都是空的。我想这是因为我们使用硬编码的攻击值('100','110','120')。任何想法如何填充其他行? – zemirco

+0

我没有注意到,但您的条件聚合只针对* attack *值进行过滤:'count(*)filter(where tag = 100)'。我调整了以适应其他水平。我假设数值是10增量,0/10/20。 – Parfait

+0

谢谢!按预期工作。最后一个问题。即使缺少类别,是否可以始终获得6行?例如,比赛刚刚开始,并且没有任何块(类别2)。目前我只得到5排。我能以某种方式总是得到所有具有0值的行以查找缺失的类别吗? – zemirco