增量总计

时间:2011-12-06 16:41:18

标签: php mysql

我有一个应用程序计算总使用成本......

使用表

terminal   calldate      callduration   tariff
1          2011-01-01    00:01:00       1
1          2011-01-01    00:03:30       1
1          2011-01-02    00:10:00       1
1          2011-01-05    01:00:00       1

关税表

id     included      extraunit        extracost
1      00:05:00      00:01:00         10

使用上面的表我计算出每个终端每月的总成本,首先我将所有时间转换为秒,然后使用以下公式计算成本

cost = ((totalduration - included) / extraunit ) * extracost
695  = ((4470          - 300)      / 60        ) * 10

如果totalduration - included为负,则费用为0

我在PHP中进行计算。这一切都很好 - 我可以为每个终端创建一个发票,并且每个终端每月显示费用。

Month        Terminal     Cost
2011-01      1            695

我现在需要做的是在原始使用表中添加一个列(我可以使用一个单独的表 - 但是对于这个问题保持简单)来记录使用表中每条记录的成本。

所以 - 我知道每月的总费用,并且可以查询使用表以获得构成该费用的所有记录 - 我无法弄清楚我是如何在考虑所包含的时间的同时分配费用的。如果没有包含时间,我会将总费用除以总持续时间,然后确定每个记录的费用。我可以通过计算每秒的费用695 / 4170 = 0.1666666667来做到这一点 - 然后我找出工作每条记录的成本。这是我想要实现的输出。

terminal   calldate      callduration   tariff      cost
1          2011-01-01    00:01:00       1           0.00
1          2011-01-01    00:03:30       1           0.00
1          2011-01-02    00:10:00       1          95.00 (rounded to 2 decimal places)
1          2011-01-05    01:00:00       1         600.00 (rounded to 2 decimal places)

第1行用户距离包含的分钟60秒,第2行使用210秒,第3行使用包含5分钟的30秒 - 计算第3行的剩余部分(570秒)。

有人可以指出我正确的方向 - 我认为这不可能完全在MySQL中做...但如果我至少只能得到需要的记录那将是非常好的成本申请 - 即忽略所包含的记录。

使用表每月包含8000万条记录(有800,000个终端) - 所以它需要很好地扩展...

更新

每月创建每个终端总费用的过程大约需要3个小时 - 为了缩短这个时间我使用 - sum(time_to_sec(callduration))对呼叫持续时间进行分组,这样我就可以获得每个终端每月的总费用。这个成本是第一重要的,应该尽快提供 - 每次使用的成本并不那么紧急,需要“一段时间” - 这就是为什么我可以使用一个单独的过程来解决这个问题 - 也许它更好重新审视原计划?并且可能计算出每个使用线的成本,然后总计这些?

更新2

添加了一些预期的输出和一些关于如何计算每条记录的成本的更多细节 - 我有所有的计算 - 这是直接的部分 - 困难在于解决所包含的内容和不包含的内容......

感谢任何帮助/建议。

1 个答案:

答案 0 :(得分:2)

如果总成本是按总计计算的,那么每次使用的成本将难以计算并使其与总成本相加并匹配。 例如

terminal   calldate      callduration   tariff
1          2011-01-01    00:01:00       1 - uses 1m of the included time
1          2011-01-01    00:03:30       1 - uses 3m30 of the included time
1          2011-01-02    00:10:00       1

这里发生了什么?这包括30s的包含时间吗?如果是这样的话,如果你的单位是1米,其他9分30秒如何分解?是按比例计算的吗?

就每月摘要而言,我可能会每个终端逐日建立起来,所以你会得到类似的东西

terminal   calldate      included   extra_duration   cost
1          2011-01-01    00:04:30      00:00:00        0
1          2011-01-02    00:05:00      00:09:30       90
1          2011-01-05    00:05:00      00:10:30      100

然后每天您可以总结前一天每个终端分配的时间,并使用更新的计算添加一个新行。

修改 我相信你可以在纯sql中做到这一点。这应该让你开始:

SET @cumul = 0;
SELECT id,(@cumul:= @cumul + TIME_TO_SEC( duration ) ) FROM `usage`;

从那以后,您应该能够添加累积持续时间列并从中进行操作,或者您可以将其拼接到UPDATE中,并使用CASE语句记录每次使用的实际成本。

修改 好的,鉴于您的意见,我认为如果您想在纯SQL中执行此操作。它需要2个额外的列(cumul_duration和cost)。

SET @cumul = 0;
UPDATE `usage` set cumul_duration=(@cumul:= @cumul + TIME_TO_SEC( duration ));
update `usage` set cost=(
SELECT
    CASE WHEN cumul_duration<=300
    THEN 0
    ELSE (
        CASE WHEN (cumul_duration-TIME_TO_SEC(duration)>=300)
        THEN (TIME_TO_SEC(duration)*10/60)
        ELSE ((cumul_duration-300)*10/60) END
) END
)

我还没有弄清楚如何在一个查询中完成所有操作,而我没有针对多个关税进行测试,但它适用于您的样本数据。