sql - 在 PostgreSQL 中用每个用户的最新值填充缺失的日期

标签 sql postgresql window-functions generate-series

我有一个表dayload,用于标记用户每天的工作时间何时发生变化。

| id | date       | user_id | hours |
| 1  | 2019-01-27 | 1       | 4     |
| 2  | 2019-02-01 | 1       | 8     |
| 3  | 2018-06-30 | 2       | 5     |
| 4  | 2018-07-02 | 2       | 8     |

因此该表仅跟踪更改。我想要得到的是一系列连续的日期以及当前有效的时间。

例如我想知道 2018-01-01 到 2019-02-28 之间每个用户和日期的工作时间,即

| id  | date       | user_id | hours |
| ..  | 2018-01-27 | 1       | 4     |
| ..  | 2018-01-28 | 1       | 4     |
| ..  | 2018-01-29 | 1       | 4     |
| ..  | 2018-01-30 | 1       | 4     |
| ..  | 2018-01-31 | 1       | 4     |
| ..  | 2019-02-01 | 1       | 8     |
| ..  | 2019-02-02 | 1       | 8     |
| ..  | 2019-02-03 | 1       | 8     |
| ..  | 2019-02-04 | 1       | 8     |
           ...
| ..  | 2018-06-30 | 2       | 5     |
| ..  | 2018-07-01 | 2       | 5     |
| ..  | 2018-07-02 | 2       | 8     |
| ..  | 2018-07-03 | 2       | 8     |
           ...

我不知道如何填空,正如我所描述的那样。我考虑过创建一个只包含 1900 年到 2100 年之间日期的表,但我想不出如何使用日期表来填充空白。

我读过有关generate_series的内容,我尝试过以不同的方式加入数据,我还尝试使用PostgresSQL的窗口函数。但我不知道怎么办。

我与日期表最接近,但问题是如果用户的最新行的日期超出我想要查询的范围,则不会显示在结果中。这是我尝试过的查询:

SELECT user_id, d.date, minutes

    FROM day d

    JOIN dayload dl

    ON dl.date = (
        SELECT MAX(date) from DAYLOAD where date <= d.date
    )
    order by d.date;

我将用户表等加入到此关系中,但是当我将日期范围过滤应用于查询时,那些具有日期范围之外的最新日负载的行将被遗漏。

最佳答案

我认为这符合你的要求:

select generate_series(date,
                       lead(date, 1, current_date) over (partition by user_id order by date) - interval '1 day',
                       interval '1 day'
                      ) as date,
       user_id, hours
from (values (1, '2019-01-27'::date, 1, 4),
             (2, '2019-02-01'::date, 1, 8),
             (3, '2018-06-30'::date, 2, 5)
     ) v(id, date, user_id, hours);

这是一个generate_series()的“简单”应用程序。 lead() 正在获取用户的下一个日期。减去一天的复杂性以及所有这些,这样日子就不会重叠。

Here是一个数据库<> fiddle 。

关于sql - 在 PostgreSQL 中用每个用户的最新值填充缺失的日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54909729/

相关文章:

sql - 如何用同一表中另一列的值替换一列的值

Postgresql、libpq、C

SQL 窗口函数 - SELECT DISTINCT ORDER BY LIMIT

SQL Server 删除时间戳超过 1 个月的行

sql - Oracle错误: ORA-01839: date not valid for month specified

sql - 根据另一个表中的自定义属性过滤值

sql - 在hive窗口中,如果CURRENT ROW的值小于UNBOUNDED PRECEDING的值会发生什么

postgresql - 将 Heroku Postgres 从 dev 更新到 basic

postgresql - 如何在 PostgreSQL 中使用触发器在表中插入新行时创建新模式?

sql - PostgreSQL - 如何创建带条件的窗口框架?