计算当月的账单使用情况

时间:2018-07-26 02:03:14

标签: mysql sql

我正在尝试计算当月的存储使用情况。表格的外观如下:

stored_on              deleted_on          amount_in_gb    rate_per_gb_per_month
2014-01-01 12:00:00    2014-05-09 00:00:00   20            0.05 
2015-01-01 00:00:00    NULL                  4.2            0.05 
2015-01-01 12:00:00    2015-01-09 00:00:00   7.2            0.05 
2016-01-01 12:00:00    NULL                  100            0.05 

要获取2015年1月的使用量,应为:

  $0.05 * 20 * 0        = $0.00 (this item was deleted before the start of the month)
+ $0.05 * 4.2 * 1       = $0.21 (for the second line item, the item is stored for a full month)
+ $0.05 * 7.2 * (~8/31) = $0.09 (stored for about 8 of 31 days in the month)
+ $0.05 * 100 * 0       = $0.00 (this item was added after this month)
---------------------------------
TOTAL                   = $0.30

如何在SQL中执行上述操作?基本上,在给定特定月份的情况下,要计算该月份的使用情况,请考虑到stored_on值可能在该月份开始之前,该月份期间或该月份之后的事实;与deleted_on值相同。

2 个答案:

答案 0 :(得分:2)

这应该计算一月份的按比例分配的金额:

select sum( rate_per_gb_per_month * amount_in_gb *
        greatest(1 +
                 datediff(least('2015-01-31', coalesce(deleted_on, '2015-01-31')) ,
                          greatest('2015-01-01', stored_on)
                         ), 0
             ) / DAY(LAST_DAY('2015-01-01'))  
      ) as usage_cost

from t;

Here是一个SQL提琴。

答案 1 :(得分:1)

以下内容比Gordon的回答更为冗长,但对我来说更容易理解(也对我修复语法错误)-

SELECT 
    start_date_of_storage_on_month,
    end_date_of_storage_on_month, 
    (1 + datediff(end_date_of_storage_on_month, start_date_of_storage_on_month)) num_days,
    ((1 + datediff(end_date_of_storage_on_month, start_date_of_storage_on_month)) / DAY(LAST_DAY('2015-01-01'))) * amount_in_gb * rate_per_gb_per_month total_in_usd

    FROM (select

    CASE
        when stored_on >= '2015-31-01' then NULL
        when deleted_on <= '2015-01-01' then NULL
        else date(greatest('2015-01-01', stored_on))
    END start_date_of_storage_on_month,

    CASE
        when deleted_on is null then '2015-01-31'
        when deleted_on >= '2015-31-01' then '2015-01-31'
        else date(deleted_on)
    END end_date_of_storage_on_month,
    billing.*

from billing) t

这将给出正确的$ 0.31值,尽管它将按行项目显示每个值-要获得总和,只需对SUM(...)值进行total_in_usd