Postgres width_bucket()没有正确地为存储桶分配值

时间:2016-12-06 11:26:26

标签: sql postgresql

在postgresql 9.5.3中,我无法按预期工作width_bucket(),它似乎是将值分配给错误的存储桶。

数据集:

   1
   2
   4
  32
  43
  82
 104
 143
 232
 295
 422
 477

预期输出(添加桶范围和零计数行以帮助分析):

 bucket | bucketmin | bucketmax | Expect | Actual
--------+-----------+-----------+--------|--------
      1 |         1 |      48.6 |      5 |      5 
      2 |      48.6 |      96.2 |      1 |      2 
      3 |      96.2 |     143.8 |      2 |      1 
      4 |     143.8 |     191.4 |      0 |      0 
      5 |     191.4 |       239 |      1 |      1 
      6 |       239 |     286.6 |      0 |      1 
      7 |     286.6 |     334.2 |      1 |      0 
      8 |     334.2 |     381.8 |      0 |      1 
      9 |     381.8 |     429.4 |      1 |      0 
     10 |     429.4 |       477 |      1 |      1 

实际输出:

 wb | count
----+-------
  1 |     5
  2 |     2
  3 |     1
  5 |     1
  6 |     1
  8 |     1
 10 |     1

生成实际输出的代码:

create temp table metrics (val int);
insert into metrics (val) values(1),(2),(4),(32),(43),(82),(104),(143),(232),(295),(422),(477);
with metric_stats as (
    select
        cast(min(val) as float) as minV,
        cast(max(val) as float) as maxV
    from metrics m
),
hist as (
    select 
        width_bucket(val, s.minV, s.maxV, 9) wb,
        count(*)
    from metrics m, metric_stats s
    group by 1 order by 1
)
select * from hist;

1 个答案:

答案 0 :(得分:1)

您的计算似乎已关闭。以下查询:

with metric_stats as (
      select cast(min(val) as float) as minV,
             cast(max(val) as float) as maxV
      from metrics m
     )
select g.n,
       s.minV + ((s.maxV - s.minV) / 9) * (g.n - 1) as bucket_start,
       s.minV + ((s.maxV - s.minV) / 9) * g.n as bucket_end
from generate_series(1, 9) g(n) cross join
     metric_stats s
order by g.n

产生以下垃圾箱:

1 1                53.8888888888889
2 53.8888888888889 106.777777777778
3 106.777777777778 159.666666666667
4 159.666666666667 212.555555555556
5 212.555555555556 265.444444444444
6 265.444444444444 318.333333333333
7 318.333333333333 371.222222222222
8 371.222222222222 424.111111111111
9 424.111111111111 477

如果你想要10个桶,我认为你打算让“9”成为“10”。