我在 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
但值得一试。
造成这种巨大差异的另一种可能性是,在 UPDATE
和 SHOW 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/