我有一个大致遵循这个模式的表:
Table Name: history
╔════╤══════╤══════════╤═════╤═════════════════════╗
║ id │ stat │ stat_two │ ... │ updated_at ║
╠════╪══════╪══════════╪═════╪═════════════════════╣
║ 1 │ 100 │ 5 │ ... │ 2019-01-01 12:30 PM ║
╟────┼──────┼──────────┼─────┼─────────────────────╢
║ 1 │ 105 │ 7 │ ... │ 2019-01-02 12:30 PM ║
╟────┼──────┼──────────┼─────┼─────────────────────╢
║ 1 │ 300 │ 10 │ ... │ 2019-02-01 12:30 PM ║
╟────┼──────┼──────────┼─────┼─────────────────────╢
║ 1 │ 700 │ 20 │ ... │ 2019-05-01 12:30 PM ║
╟────┼──────┼──────────┼─────┼─────────────────────╢
║ 2 │ 50 │ 0 │ ... │ 2019-01-01 12:30 PM ║
╟────┼──────┼──────────┼─────┼─────────────────────╢
║ 2 │ 55 │ 0 │ ... │ 2019-01-02 12:30 PM ║
╟────┼──────┼──────────┼─────┼─────────────────────╢
║ 2 │ 75 │ 3 │ ... │ 2019-02-01 12:30 PM ║
╟────┼──────┼──────────┼─────┼─────────────────────╢
║ 2 │ 90 │ 7 │ ... │ 2019-05-01 12:30 PM ║
╚════╧══════╧══════════╧═════╧═════════════════════╝
桌子很大。
我试图产生以下结果,而过滤只包括一些 IDS(比如只有 1 和 2):
╔═════════╤═══════════════════╤═══════════════════════════════════════════════╤═══════════════════════════════════════════════════╗
║ month │ count_of_ids_seen │ sum_of_(last_seen_stat_for_that_month per ID) │ sum_of_(last_seen_stat_two_for_that_month per ID) ║
╠═════════╪═══════════════════╪═══════════════════════════════════════════════╪═══════════════════════════════════════════════════╣
║ 2019-01 │ 2 │ 160 │ 7 ║
╟─────────┼───────────────────┼───────────────────────────────────────────────┼───────────────────────────────────────────────────╢
║ 2019-02 │ 2 │ 375 │ 13 ║
╟─────────┼───────────────────┼───────────────────────────────────────────────┼───────────────────────────────────────────────────╢
║ 2019-03 │ 2 │ 375 │ 13 ║
╟─────────┼───────────────────┼───────────────────────────────────────────────┼───────────────────────────────────────────────────╢
║ 2019-04 │ 2 │ 375 │ 13 ║
╟─────────┼───────────────────┼───────────────────────────────────────────────┼───────────────────────────────────────────────────╢
║ 2019-05 │ 2 │ 790 │ 27 ║
╚═════════╧═══════════════════╧═══════════════════════════════════════════════╧═══════════════════════════════════════════════════╝
我试过last_value窗口函数,可以得到出现的记录,但问题是我需要数据滞后,如果记录没有出现在表中。假设,例如第 3 个月,因为没有记录,我们应该取之前日期的最后一次看到的记录。
我当前的解决方案使用 <= 连接,这是瓶颈,当尝试数百万个 Id 时,它太慢了,不会以我需要的速度运行。
我加入了一个像这样的generate_series:
FROM
(SELECT month::date FROM generate_series('2018-03-01'::date, '2019-06-01'::date, '1 month') month) d
LEFT JOIN
history h
ON date_trunc('month', h.updated_at) <= d.month
关于如何更有效地执行此操作并删除 <= 连接的任何想法?这会导致嵌套循环并造成开销太大。