Postgresql
當時間序列中的值為空時返回上一個執行總計
這是上一個問題的延續,其中可以找到表定義和範例數據。(非常感謝@Erwin Brandstetter 的幫助)。
所有這些都是在 PostgreSQL 11.5 DB 上完成的。
SELECT * FROM ( SELECT the_day::date FROM generate_series(timestamp '2020-01-01', date_trunc('day', localtimestamp), interval '1 day') the_day ) d LEFT JOIN ( SELECT customer_id , created_at::date AS the_day , sum(sum(t.amount) FILTER (WHERE stock_ticker = 'tsla')) OVER w AS tsla_running_amount , sum(sum(t.amount) FILTER (WHERE stock_ticker = 'goog')) OVER w AS goog_running_amount FROM transactions t WHERE created_at >= timestamp '2020-01-01' GROUP BY customer_id, created_at::date WINDOW w AS (PARTITION BY customer_id ORDER BY created_at::date) ) t USING (the_day) ORDER BY customer_id, the_day;
當客戶一天沒有交易時,我需要能夠顯示該客戶當天的“最近”執行總計。
例如:
2020-01-01:客戶購買 5 個“tsla”,總餘額為 5。 2020-01-02:客戶不採取任何行動。目前總餘額顯示為 5。 2020-01-03:客戶賣出 2 個“tsla”,現在總餘額 3 個。 2020-01-04:客戶不採取任何行動。目前餘額仍顯示為 3。
目前,按照這種設置方式,客戶在沒有交易的那一天的記錄將作為餘額總計的 NULL 行返回。
我如何在他們沒有交易的日子裡顯示他們的“最近”執行餘額?
此查詢將為表中存在的所有客戶執行
transactions
(過去至少有一次交易)。
一種方法是在執行視窗函式
(customer_id, the_day)
之前生成一行。像:SELECT c.customer_id, d.the_day , sum(t.tsla_amount) OVER w AS tsla_running_amount , sum(t.goog_amount) OVER w AS goog_running_amount FROM ( SELECT the_day::date FROM generate_series(timestamp '2020-01-01' , date_trunc('day', localtimestamp) , interval '1 day') the_day ) d CROSS JOIN (SELECT DISTINCT customer_id FROM transactions) c -- ! LEFT JOIN ( SELECT customer_id , created_at::date AS the_day , sum(t.amount) FILTER (WHERE stock_ticker = 'tsla') AS tsla_amount , sum(t.amount) FILTER (WHERE stock_ticker = 'goog') AS goog_amount FROM transactions t WHERE created_at >= timestamp '2020-01-01' GROUP BY customer_id, created_at::date ) t USING (customer_id, the_day) WINDOW w AS (PARTITION BY customer_id ORDER BY the_day) ORDER BY customer_id, the_day;
db<>在這裡擺弄
如果表很大,並且只有相對較少的不同客戶,您可能需要優化性能。看:
但是你通常會有一個單獨的客戶表來處理……
如果您希望在客戶的第一次交易之前
0
而不是在行中,請添加. 像:NULL
COALESCE
SELECT c.customer_id, d.the_day , COALESCE(sum(t.tsla_amount) OVER w, 0) AS tsla_running_amount , COALESCE(sum(t.goog_amount) OVER w, 0) AS goog_running_amount FROM ...