web-dev-qa-db-ja.com

レコードをフィルタリングする場合でも、最初から各行の実行合計を計算します

私はこの簡略化されたテーブルentriesを持っています:

----------------------------
| id | date       | amount |
----------------------------
| 1  | 2017-12-01 | 100    |
----------------------------
| 2  | 2017-12-03 | 100    |
----------------------------
| 3  | 2017-12-05 | 100    |
----------------------------

他の列と一緒にbalance列の実行中の合計(amount)をクエリする必要があります。

私は簡単なクエリを思いつきました:

SELECT id, date, amount, SUM(amount) OVER (ORDER BY date) AS balance
FROM entries
GROUP BY id, date, amount
ORDER BY date

次のように表示されます。

--------------------------------------
| id | date       | amount | balance |
--------------------------------------
| 1  | 2017-12-01 | 100    | 100     |
-------------------------------------
| 2  | 2017-12-03 | 100    | 200     |
-------------------------------------
| 3  | 2017-12-05 | 100    | 300     |
-------------------------------------

ここで、日付に基づいて結果をフィルター処理する必要がありますが、balance列は、開始日、つまり2017-12-01(またはテーブルの最初のレコード)から計算する必要があります。

つまり、WHERE date >= '2017-12-03'、それでも、各行の残高を日付範囲なしの場合と同じにしたいと思います。

--------------------------------------
| id | date       | amount | balance |
--------------------------------------
| 2  | 2017-12-03 | 100    | 200     |
-------------------------------------
| 3  | 2017-12-05 | 100    | 300     |
-------------------------------------

どうすればこれを達成できますか?

2
Code Poet

それを副選択でラップするだけです。

SELECT *
FROM (
  SELECT id, date, amount, SUM(amount) OVER (ORDER BY date, id) AS balance
  FROM entries
  GROUP BY id, date, amount
)
WHERE date >= '2017-12-03'
ORDER BY date, id;

また、グループ化する必要がない3つの行がある場合、いくつかの点で混乱しています。これにより同じ結果が得られるかどうかを確認してください。はるかに高速です。

SELECT *
FROM (
  SELECT id, date, amount, SUM(amount) OVER (ORDER BY date, id) AS balance
  FROM entries
)
WHERE date >= '2017-12-03'
ORDER BY date, id;
3
Evan Carroll