我有一张桌子'消费'在mysql中有大约500万条记录,如:
month from | month to | consumption
2012-12-20 2013-01-10 200
2013-01-11 2013-02-13 345
有没有办法让每个月的消费量如下: 1月份的消费量(2013-01-01至2013-01-31)= ...,2月份= ....价值可以是估计的数字,不一定是完美的。
我想过将每天的平均消耗量乘以不同日期范围的月份天数,但不确定如何使用它。
更新:
@Karolis使用原始的excel公式,我得到的估计消耗值高于使用sql脚本计算的值。据我所知,sql脚本和excel公式都在进行相同的计算。能否帮助我找出原因,并使sql脚本消耗值与使用excel获得的值相同。
原始表:
id month_from month_to consumption
121 2009-12-30 2009-01-28 1251 <-First period
121 2010-01-29 2010-02-24 915 <-Second period
993 xxxx-xx-xx xxxx-xx-xx xxx
121 2010-02-25 2010-03-25 741
121 2010-03-26 2010-04-28 1508
我使用了您提供的脚本,进行了一些修改,并按ID添加了一个组,并按ID排序,我使用的脚本是:
SELECT
m.month, id,
SUM(
-- partial consumption = date subrange / date range * consumption
(
DATEDIFF(
IF(c.date_to > m.last_day, m.last_day, c.date_to),
IF(c.date_from < m.first_day, m.first_day, c.date_from)
) + 1
) / (DATEDIFF(c.date_to, c.date_from) + 1) * c.consumption
) consumption
FROM
consumption c
JOIN (
-- series of months
SELECT DISTINCT
DATE_FORMAT(date_from, '%Y %M') month,
DATE_FORMAT(date_from, '%Y-%m-01') first_day,
LAST_DAY(date_from) last_day
FROM consumption
GROUP BY date_from -- redundant, but for speed purposes
) m ON
-- condition indicating a date range belongs to a particular
-- month (fully or partially)
c.date_from <= m.last_day AND c.date_to >= m.first_day
GROUP BY m.month, id
ORDER BY m.month, id
Excel公式:
if((idInCurrentLine = idInNextLine), ((((month_to - start_date) + 1 )*consumptionPerDayForFirstPeriod/day ) + (start_date - month_from) * consumptionPerDayForsecondPeriod/day), "")
consumptionPerDayForFirstPeriod = consumptionFortheFirstPeriod/((month_to - month_from)+ 1)
consumptionPerDayForSecondPeriod = consumptinoFortheSecondPeriod/((month_to - month_from)+ 1)
在给出的例子中
idInCurrentLine = 121, idInNextLine = 121
使用这两个我计算的估计消耗和结果是:
估计消耗量:(正如您所看到的,两种情况下的估计值存在差异,使用excel的估计值高于sql。
Month Using Excel Using mysql script
2009 january 1313.4 1269.3
2009 Febuary 950.47 915.5
2009 March 935.78 904..9
xxxx xxxx xxxxx
xxxx xxxx xxxxx
答案 0 :(得分:2)
SELECT
m.month,
SUM(
-- partial consumption = date subrange / date range * consumption
(
DATEDIFF(
IF(c.month_to > m.last_day, m.last_day, c.month_to),
IF(c.month_from < m.first_day, m.first_day, c.month_from)
) + 1
) / (DATEDIFF(c.month_to, c.month_from) + 1) * c.consumption
) consumption
FROM
consumption c
JOIN (
-- series of months
SELECT DISTINCT
DATE_FORMAT(month_from, '%Y %M') month,
DATE_FORMAT(month_from, '%Y-%m-01') first_day,
LAST_DAY(month_from) last_day
FROM consumption
GROUP BY month_from -- redundant, but for speed purposes
) m ON
-- condition indicating that a date range belongs
-- to a particular month (fully or partially)
c.month_from <= m.last_day AND c.month_to >= m.first_day
GROUP BY m.first_day
ORDER BY m.first_day
答案 1 :(得分:0)
Datediff是你的朋友 - 试试consumption * 30 / Datediff(day, monthfrom, monthto)
答案 2 :(得分:-2)
简而言之,你会使用BETWEEN:
SELECT consumption from [table] where [input date] is between [monthFrom] and [monthTo]
输入日期是范围内的区域。