我在DB2 SQL DB中有一系列计算时间,这些计算时间存储为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
)
使用sproc。我按如下方式计算总和:
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之间的计算,其中最大单个计算的总百分比(如上所计算)为12%,批次的计算范围为0.00000N%。
要计算我使用简单查询的总百分比:
SELECT
SUM(C.CALC_TIME_PERCENTAGE)
FROM
MY_SCHEMA.MY_CALC_DATA_TABLE C
WHERE
C.CALCDATE = P_DATE;
有什么建议吗?
更新:重新排列计算结果。建议修复问题。谢谢。 BTW在DB2中,FLOAT和DOUBLE是相同的类型。现在阅读有关花车的建议论文。
答案 0 :(得分:3)
如果字段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)
但是你提到某个日期的计算中有很多行,因此它可能是一个舍入错误。尝试在两个字段(或至少DOUBLE
字段)中使用CALC_TIME_PERCENTAGE
数据类型,看看与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
操作之间的表中删除行。
您可以通过运行计算(没有UPDATE)并总结来测试是否发生这种情况:
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
答案 1 :(得分:2)
可能是一个舍入问题。请尝试使用C.INDIV_CALC_DURATION_IN_S * 100 / V_TOTAL_CALC_TIME_IN_S
。
答案 2 :(得分:1)
如果C.INDIV_CALC_DURATION_IN_S
非常小,但您有大量行(因此V_TOTAL_CALC_TIME_IN_S
会变大),那么
(C.INDIV_CALC_DURATION_IN_S / V_TOTAL_CALC_TIME_IN_S) * 100
可能会失去精确度,尤其是在您使用FLOAT
时。
如果是这种情况,则将计算(如其他地方所述)更改为
(C.INDIV_CALC_DURATION_IN_S * 100) / V_TOTAL_CALC_TIME_IN_S
应该增加总数,虽然它可能无法让你一直到100%
如果是这种情况并且很多测量都是小部分时间,我会考虑超越这个程序:是否可以记录时间,例如毫秒或微秒?要么为你提供额外的有效数字空间。