sql - 为什么这个百分比总和不等于 100%?

标签 sql db2 sum

我在 DB2 SQL 数据库中有一系列计算时间,它们存储为默认值为 0.0 的 float 。

正在更新的表格如下:

CREATE TABLE MY_CALC_DATA_TABLE
(
    CALCDATE                 TIMESTAMP,
    INDIV_CALC_DURATION_IN_S FLOAT WITH DEFAULT 0.0,
    CALC_TIME_PERCENTAGE     FLOAT WITH DEFAULT 0.0
)

使用存储过程。我计算总和如下:

CREATE OR REPLACE PROCEDURE MY_SCHEMA.MY_SPROC (IN P_DATE TIMESTAMP)
    LANGUAGE SQL
    NO EXTERNAL ACTION
BEGIN
    DECLARE V_TOTAL_CALC_TIME_IN_S FLOAT DEFAULT 0.0;

    -- other stuff setting up and joining data

    -- Calculate the total time taken to perform the
    -- individual calculations

    SET V_TOTAL_CALC_TIME_IN_S =
        (
            SELECT
                SUM(C.INDIV_CALC_DURATION_IN_S)
            FROM
                MY_SCHEMA.MY_CALC_DATA_TABLE C
            WHERE
                C.CALCDATE = P_DATE
        )

    -- Now calculate each individual calculation's percentage
    -- of the toal time.

    UPDATE
        MY_SCHEMA.MY_CALC_DATA_TABLE C
    SET
        C.CALC_TIME_PERCENTAGE =
            (C.INDIV_CALC_DURATION_IN_S / V_TOTAL_CALC_TIME_IN_S) * 100
    WHERE
        C.CALCDATE = P_DATE;

END@

问题是,当我对指定 CALC_DATE 的所有 CALC_TIME_PERCENTAGE 值求和时,它总是小于 100%,而对于不同的 CALC_DATES,总和为 80% 或 70% 之类的值。

我们在这里讨论的是 35k 到 55k 的计算,最大单个计算占总数的百分比,如上计算,为 11%,很多计算在 0.00000N% 范围内。

要计算我使用简单查询的总百分比:

SELECT
    SUM(C.CALC_TIME_PERCENTAGE)
FROM
    MY_SCHEMA.MY_CALC_DATA_TABLE C
WHERE
    C.CALCDATE = P_DATE;

有什么建议吗?

更新:重新排列计算。按照建议解决了问题。谢谢。顺便说一句,在 DB2 中,FLOAT 和 DOUBLE 是同一类型。现在阅读建议的关于 float 的论文。

最佳答案

如果字段 C.INDIV_CALC_DURATION_IN_S 是整数,我会认为这是一个舍入错误。再次阅读,这不是问题,因为数据类型是 FLOAT

您仍然可以尝试使用它。如果这产生的结果与以前的方法(略有不同),我不会感到惊讶:

SET
    C.CALC_TIME_PERCENTAGE =
        (C.INDIV_CALC_DURATION_IN_S * 100.0 / V_TOTAL_CALC_TIME_IN_S)

但是您提到某个日期的计算中有很多行,因此可能是舍入误差。尝试在两个字段(或至少 CALC_TIME_PERCENTAGE 字段)中使用 DOUBLE 数据类型,看看与 100% 的差异是否变小。

我不确定 DB2 是否有 DECIMAL(x,y) 数据类型。在这种情况下可能更合适。


另一个问题是如何找到 CALC_TIME_PERCENTAGE 的总和。我想您(和其他所有人)会使用:

        SELECT
            P_DATE, SUM(CALC_TIME_PERCENTAGE)
        FROM
            MY_SCHEMA.MY_CALC_DATA_TABLE C
        GROUP BY P_DATE

这样,您就无法确定求和的顺序。甚至可能无法确定,但您可以尝试:

        SELECT
            P_DATE, SUM(CALC_TIME_PERCENTAGE)
        FROM
          ( SELECT
                P_DATE, CALC_TIME_PERCENTAGE
            FROM
                MY_SCHEMA.MY_CALC_DATA_TABLE C
            ORDER BY P_DATE
                   , CALC_TIME_PERCENTAGE ASC
          ) AS tmp
        GROUP BY P_DATE

优化器可能会忽略内部 ORDER BY 但值得一试。


造成这种巨大差异的另一种可能性是,在 UPDATESHOW percent SUM 操作之间,行从表中删除。

您可以通过运行计算(不更新)并总结来测试是否会发生这种情况:

        SELECT
            P_DATE
          , SUM( INDIV_CALC_DURATION_IN_S * 100.0 / T.TOTAL )                   
            AS PERCENT_SUM
        FROM
            MY_SCHEMA.MY_CALC_DATA_TABLE C
          , ( SELECT SUM(INDIV_CALC_DURATION_IN_S) AS TOTAL
              FROM MY_SCHEMA.MY_CALC_DATA_TABLE
            ) AS TMP
        GROUP BY P_DATE

关于sql - 为什么这个百分比总和不等于 100%?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6596074/

相关文章:

mysql - 尝试使用 SQL 查询获取每天的项目数

python - 使 numpy.sum() 返回矩阵总和而不是单个数字

SQL select 语句结合不同的表

mysql - 在 > 和 < SQL 之间查找

windows - Windows 7 和 Linux 之间的 DB2 和 jRuby on Rails 操作系统兼容性

sql-server - 两个查询的效率更高?

mysql - SUM 后在 SQL 查询中查找 AVG 值 - 组函数的使用无效

mysql - 如何返回 sum() 行

sql - Postgres - 使用 where 子句的慢速简单连接

db2 - 在 SquirrelSQL 中显示 db2 错误代码