我正在尝试计算当月的存储使用情况。表格的外观如下:
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
值相同。
答案 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
。