我在DB2SQLDB中有一系列的计算时间,它们存储为float,默认值为0.0。
正在更新的表如下:
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的建议文章。
3条答案
按热度按时间5anewei61#
如果字段
C.INDIV_CALC_DURATION_IN_S
是Integer,我会假设它是一个舍入错误。再次阅读,这不是问题,因为数据类型是FLOAT
。你仍然可以尝试使用这个方法。如果这个方法产生的结果与之前的方法略有不同,我不会感到惊讶:
但是您提到在某个日期的计算中有很多行,因此这可能是一个舍入误差。请尝试在两个字段(或至少在
CALC_TIME_PERCENTAGE
字段)中使用DOUBLE
数据类型,看看与100%
的差异是否会变小。我不确定
DB2
是否有DECIMAL(x,y)
数据类型,在这种情况下可能更合适。另一个问题是如何求出
CALC_TIME_PERCENTAGE
的和。我想你(和其他人)会使用:这样,你就无法确定求和的顺序,甚至无法确定,但你可以试试看:
优化器可能会忽略内部的
ORDER BY
,但值得一试。造成这种巨大差异的另一种可能性是,在
UPDATE
和SHOW percent SUM
操作之间从表中删除了行。您可以通过运行计算(不使用UPDATE)并求和来测试是否会发生这种情况:
sycxhyv72#
可能是舍入问题。请改用
C.INDIV_CALC_DURATION_IN_S * 100 / V_TOTAL_CALC_TIME_IN_S
。bfhwhh0e3#
如果
C.INDIV_CALC_DURATION_IN_S
非常小,但您有大量的行(因此V_TOTAL_CALC_TIME_IN_S
相比之下变得很大),则很可能会丢失精度,尤其是在使用
FLOAT
时。如果是这种情况,则将计算(如其他地方所述)更改为
我应该增加总数,虽然它可能不会让你一直到100%
如果是这种情况,并且很多测量都是一秒的很小一部分,我会考虑考虑这个过程之外的问题:时间可以用毫秒或微秒来记录吗?这两种方法都可以为您提供一些额外的有效数字空间。