2

我在 mysql 中有一个表“消费”,大约有 500 万条记录,例如:

month from  |   month to         |       consumption
2012-12-20     2013-01-10                  200
2013-01-11     2013-02-13                  345

有没有办法得到每个月的消费,比如:一月的消费(2013-01-01到2013-01-31)= ...,二月= ...。该值可以是估计数字,需要不完美。

我想将每天的平均消耗量乘以不同日期范围的当月天数,但不知道如何去做。

更新:

@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 
4

3 回答 3

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
于 2014-08-19T22:43:20.257 回答
0

Datediff 是你的朋友 - 试试consumption * 30 / Datediff(day, monthfrom, monthto)

于 2014-08-19T17:21:59.787 回答
-2

简而言之,您将使用 BETWEEN:

SELECT consumption from [table] where [input date] is between [monthFrom] and [monthTo]

您输入的日期是范围内的区域。

于 2014-08-19T16:56:06.330 回答