【问题标题】:Selecting the most recent value of a column from a Postgres table从 Postgres 表中选择列的最新值
【发布时间】:2020-08-18 03:56:50
【问题描述】:

我在 Postgres 表中有一些数据,如下所示:

Name | Date      | Balance
--------------------------
A    |2020-01-01 |    1
B    |2020-01-01 |    0
B    |2020-01-02 |    2
A    |2020-01-03 |    5

(请注意,A 缺少 2020-01-02B 的值 2020-01-03

我想用该名称的最新值填写缺失的日期。换句话说,我想

Name | Date      | Balance
--------------------------
A    |2020-01-01 |    1
B    |2020-01-01 |    0
A    |2020-01-02 |    1 <--- filled in with previous balance
B    |2020-01-02 |    2
A    |2020-01-03 |    5
B    |2020-01-03 |    2 <--- filled in with previous balance

请注意,实际上,可能会连续缺少多个日期,在这种情况下,应始终选择该名称的最新日期。

【问题讨论】:

    标签: sql postgresql date select window-functions


    【解决方案1】:

    我在想generate_series() 和窗口函数:

    select 
        n.name, 
        s.date, 
        coalesce(t.balance, lag(balance) over(partition by n.name order by s.date) balance
    from (select generate_series(min(date), max(date), interval '1 day') date from mytable) s
    cross join (select distinct name from mytable) n
    left join mytable t on t.name = n.name and t.date = s.date
    order by n.name, s.date
    

    如果您可能连续丢失多个日期,则需要更多逻辑 - 这基本上模拟了 lag()ignore nulls 选项:

    select
        name,
        date,
        coalesce(balance, first_value(balance) over(partition by name, grp)) balance
    from (
        select 
            n.name, 
            s.date, 
            t.balance,
            sum( (t.balance is not null)::int ) over(partition by n.name order by s.date) grp
        from (select generate_series(min(date), max(date), interval '1 day') date from mytable) s
        cross join (select distinct name from mytable) n
        left join mytable t on t.name = n.name and t.date = s.date
    ) t
    order by name, date
    

    【讨论】:

    • 这太好了,谢谢!最后一个问题,如果我希望能够在某个日期之上进行过滤,但仍让合并余额包含最近的值(即使该值在给定日期之前),该怎么办?
    • @Octodone:您需要将查询转换为子查询,并在外部查询中进行日期过滤。
    猜你喜欢
    • 2022-01-07
    • 1970-01-01
    • 2021-10-24
    • 2019-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多