Tôi có một balances
bảng trong PostgreSQL 9.3 trông như thế này:
CREATE TABLE balances (
user_id INT
, balance INT
, as_of_date DATE
);
INSERT INTO balances (user_id, balance, as_of_date) VALUES
(1, 100, '2016-01-03')
, (1, 50, '2016-01-02')
, (1, 10, '2016-01-01')
, (2, 200, '2016-01-01')
, (3, 30, '2016-01-03');
Nó chỉ chứa số dư cho những ngày mà người dùng đã thực hiện giao dịch. Tôi cần nó để chứa một hàng cho mỗi người dùng với số dư của họ vào mỗi ngày trong một phạm vi ngày nhất định.
- Nếu người dùng không có một hàng cho một ngày nhất định trong phạm vi, tôi cần sử dụng số dư của họ từ ngày hôm trước.
- Nếu người dùng tạo tài khoản của họ sau một ngày nhất định trong phạm vi, tôi cần tránh tạo một hàng cho kết hợp người dùng / ngày đó.
Tôi có thể tham khảo một accounts
bảng để có được người dùng create_date
:
CREATE TABLE accounts (
user_id INT
, create_date DATE
);
INSERT INTO accounts (user_id, create_date) VALUES
(1, '2015-12-01')
, (2, '2015-12-31')
, (3, '2016-01-03');
Kết quả mong muốn của tôi trông như thế này:
+---------+---------+--------------------------+
| user_id | balance | as_of_date |
+---------+---------+--------------------------+
| 1 | 100 | 2016-01-03T00:00:00.000Z |
| 1 | 50 | 2016-01-02T00:00:00.000Z |
| 1 | 10 | 2016-01-01T00:00:00.000Z |
| 2 | 200 | 2016-01-03T00:00:00.000Z |
| 2 | 200 | 2016-01-02T00:00:00.000Z |
| 2 | 200 | 2016-01-01T00:00:00.000Z |
| 3 | 30 | 2016-01-03T00:00:00.000Z |
+---------+---------+--------------------------+
Lưu ý rằng các hàng đã được thêm cho người dùng 2 cho 2016-01-02
và 2016-01-03
, mang theo số dư trước đó từ 2016-01-01
; và không có hàng nào được thêm cho người dùng 3, người được tạo trên đó 2016-01-03
.
Để tạo một chuỗi ngày trong phạm vi ngày, tôi biết tôi có thể sử dụng:
SELECT d.date FROM GENERATE_SERIES('2016-01-01', '2016-01-03', '1 day'::INTERVAL) d
... nhưng tôi đang vật lộn với LEFT JOIN
chuỗi đó với từng nhóm hàng được nhóm theo user_id
.
created_at
thì sao? Liệt kê chúng với số dư 0 cho những ngày đầu tiên? Hay với NULL? Hoặc không liệt kê cho đến khi giao dịch đầu tiên? Hay là không thể?