我有一张桌子moves
。
uuid | tag | ...
-----| ----|----
abc | 520 | ...
def | 510 | ...
ghi | 500 | ...
jkl | 310 | ...
mno | 200 | ...
tag
代表移动的类型。我们正在谈论沙滩排球的举动。第一个数字,例如520中的5,是类别。在这种情况下“服务”。我总共有六个类别:
100
,110
和120
)最后一个数字,即520的20,是结果。在这种情况下“赢”。每个类别都有3种可能的结果:
00
)10
)20
)以下是上表中的标签
以下是我想要的内容:以绝对值和相对值为每个类别提供错误,零,赢的数量。
我尝试了以下
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 | ... | ... | ... | ... | ... | ... | ...
有什么想法吗?
答案 0 :(得分:1)
考虑使用CASE
语句有条件地创建类别列,并将其作为GROUP BY
包含在派生表聚合查询中
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