【问题标题】:Total Percentage Not Adding up to 100 (postgresql)总百分比不增加100(PostgreSQL)
【发布时间】:2021-12-24 03:03:32
【问题描述】:

需要您的反馈。我正在努力使用以下代码使百分比等于 100。

SELECT animaltype, size, SUM(total) AS total,
ROUND(( SUM(total) * 100 / SUM( SUM(total)) OVER ()),2) AS percentage
FROM animals
WHERE sponsored_animalid IS NULL
GROUP BY animaltype, size
ORDER BY animaltype, size DESC;

这是输出,相当于 99.99%,因此查询不正确。

我需要将百分比列四舍五入到小数点后两位,但总数需要加起来为100。不知道是什么错误?

只要我编辑 ROUND(...,3) - 代码加起来就是 100。但我需要将数字严格四舍五入到小数点后 2 位。

这是我四舍五入到小数点后 3 位并且总数为 100 时的输出:

【问题讨论】:

  • 请参阅stackoverflow.com/q/13483430/42346 讨论解决此问题的选项。
  • 您好,感谢您的回复。我查了这个,但我需要详细说明如何在这种情况下实现最大剩余方法。
  • 你“不知道什么是错误”。 没有错误。期望任意精度的不精确值(根据定义舍入是不精确的)求和为精确值是错误的。如果将同一日期舍入到 4 位而不是 3 位会发生什么。

标签: sql postgresql percentage


【解决方案1】:

您的 SQL 语句在语法上不正确,但我明白您的意思。

这不是一个完美的解决方案,但也许您可以通过使用舍入到最接近的偶数而不是远离零的舍入函数来减少平均舍入误差:

CREATE FUNCTION myround(numeric, integer) RETURNS numeric
   LANGUAGE sql IMMUTABLE AS
'SELECT CASE WHEN abs($1 * 10::numeric ^ $2 % 1) = 0.5
            THEN round($1 * 10::numeric ^ $2 / 2, 0)
                 * 2 / 10::numeric ^ $2
            ELSE round($1, $2)
       END';

要获得真正完美的解决方案,您必须查看this question

【讨论】:

    【解决方案2】:

    解决您的问题的可能的实际解决方案是将最终汇总比上一个更精细级别的舍入少一位小数

    INSERT INTO animals (animaltype, size, total)
    VALUES 
    ('Bird', 'Small', 1615),('Bird', 'Medium', 3130),('Bird', 'Large', 8120),
    ('Cat', 'Small', 518015),('Cat', 'Medium', 250575),('Cat', 'Large', 439490),
    ('Dog', 'Small', 336680),('Dog', 'Medium', 942095),('Dog', 'Large', 978115);
            
    SELECT
    animaltype, 
    size,
    total,
    percentage_exact,
    percentage_rd2,
    sum(percentage_exact) over ()  as all_perc_exact_sum,
    sum(percentage_rd2) over ()  as   all_perc_rd2_sum,
    round(sum(percentage_rd2) over ()  ,1) as all_perc_rd2_sum_rd1
    FROM
      (
      SELECT  
      animaltype, 
      size,
      total,
      100.0 * total / (SUM(total) over ()) as percentage_exact,  
      round(100.0 * total / (SUM(total) over ()),2)  as percentage_rd2
      FROM animals       
      ) s
    
    
    | animaltype |   size |  total |     percentage_exact | percentage_rd2 | all_perc_exact_sum | all_perc_rd2_sum | all_perc_rd2_sum_rd1 |
    |------------|--------|--------|----------------------|----------------|--------------------|------------------|----------------------|
    |       Bird |  Small |   1615 | 0.046436935622305255 |           0.05 |                100 |            99.99 |                  100 |
    |       Bird | Medium |   3130 |  0.08999851919369378 |           0.09 |                100 |            99.99 |                  100 |
    |       Bird |  Large |   8120 |  0.23347858653443881 |           0.23 |                100 |            99.99 |                  100 |
    |        Cat |  Small | 518015 |    14.89475492655632 |          14.89 |                100 |            99.99 |                  100 |
    |        Cat | Medium | 250575 |    7.204913401584607 |            7.2 |                100 |            99.99 |                  100 |
    |        Cat |  Large | 439490 |   12.636884728573955 |          12.64 |                100 |            99.99 |                  100 |
    |        Dog |  Small | 336680 |     9.68073528502646 |           9.68 |                100 |            99.99 |                  100 |
    |        Dog | Medium | 942095 |   27.088547904084006 |          27.09 |                100 |            99.99 |                  100 |
    |        Dog |  Large | 978115 |   28.124249712824213 |          28.12 |                100 |            99.99 |                  100 |
    


    所以这里先取小数点后 2 位

    round(100.0 * total / (SUM(total) over ()),2)  as percentage_rd2
    

    然后将总和四舍五入到小数点后 1 位

    round(sum(percentage_2) over ()  ,1) as   all_perc_rd2_sum_rd1
    

    【讨论】:

      猜你喜欢
      • 2020-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-28
      相关资源
      最近更新 更多