Running total over date range - fill in the missing dates

前端 未结 4 1070
被撕碎了的回忆
被撕碎了的回忆 2021-01-15 03:05

I have the following table.

DATE  | AMT
10/10 | 300
12/10 | 300
01/11 | 200
03/11 | 100

How do I get the monthly total? A result like -

4条回答
  •  粉色の甜心
    2021-01-15 03:53

    To cater for missing months, create a template table to join against.

    Think of it as caching. Rather than looping through and filling gaps, just have a calendar cached in your database.

    You can even combine multiple calendars (start of month, start of week, bank holidays, working day, etc) all into one table, with a bunch of search flags and indexes.

    You end up with something like...

    SELECT
      calendar.date,
      SUM(data.amt)
    FROM
      calendar
    LEFT JOIN
      data
        ON  data.date >= calendar.date
        AND data.date <  calendar.date + INTERVAL 1 MONTH
    WHERE
          calendar.date >= '20110101'
      AND calendar.date <  '20120101'
    GROUP BY
      calendar.date
    

    EDIT

    I just noticed that the OP wants a running total.

    This -is- possible in SQL but it is extremely inefficient. The reason being that the result from one month isn't used to calculate the following month. Instead the whole running-total has to be calculated again.

    For this reason It is normally strongly recommended that you calculate the monthly total as above, then use your application to itterate through and make the running total values.

    If you really must do it in SQL, it would be something like...

    SELECT
      calendar.date,
      SUM(data.amt)
    FROM
      calendar
    LEFT JOIN
      data
        ON  data.date >= @yourFirstDate
        AND data.date <  calendar.date + INTERVAL 1 MONTH
    WHERE
          calendar.date >= @yourFirstDate
      AND calendar.date <  @yourLastDate
    GROUP BY
      calendar.date
    

提交回复
热议问题