私が歌川です

@utgwkk が書いている

MySQL で累積和を求める

SUM() と JOIN を使えば書ける.JOIN してるのでオーダーは小さくなさそうな気がする. COUNT(*) をよしなに所望のものに変えれば好きなものの累積和が取れる. テーブル名なども適宜読み替えてください.

SELECT
    t1.accum_date
  , t1.count
  , t1.count + SUM(t2.count) AS accum
FROM (
    SELECT
        DATE(created_at) AS accum_date
      , COUNT(*) AS count
    FROM
        images
    GROUP BY accum_date
    ORDER BY accum_date
) AS t1
JOIN (
    SELECT
        DATE(created_at) AS accum_date
      , COUNT(*) AS count
    FROM
        images
    GROUP BY accum_date
    ORDER BY accum_date
) AS t2
ON
    t1.accum_date > t2.accum_date
WHERE
    t1.accum_date >= TIMESTAMP '2012-07-01 00:00:00'
AND t1.accum_date < TIMESTAMP '2017-09-01 00:00:00'
GROUP BY t1.accum_date
ORDER BY t1.accum_date

t1t2 を,「それより accum_date が古い」という条件で自己結合させると,SUM(t2.count)t1 の手前までの累積和となる.

一時テーブルを使えばシュッと書けそうな気がしたが,一時テーブルは自己結合ができないので,同じサブクエリを2回書いている. PostgreSQL ならウィンドウ関数でもっと楽に書けそうなんだよなあ~~*1

gyazo.com

関係ないけど,とうとう収集してる画像の枚数が80000枚を超えました.これはそれを表すグラフです.

追記

https://www.postgresql.jp/document/9.6/html/tutorial-window.html

どれくらい短く書けるかと思ったら1行だった…….

*1:まだ試してない.