即使没有数据也能获取每个 ID 1-100 的所有数字

Get all numbers 1-100 per ID even without data

我有一个 table 看起来像这样:

ID money_earned days_since_start
1 1000 1
1 2000 2
1 3000 4
1 2000 5
2 1000 1
2 100 3

我想要那些没有 days_since_start 的行(这意味着那天 money_earned 列是空的)- 将包括每个 ID 的所有日期,“money”为 null 以指示没有收入,所以看起来像这样:

ID money_earned days_since_start
1 1000 1
1 2000 2
1 NULL 3
1 3000 4
1 2000 5
2 1000 1
1 NULL 2
2 100 3

我试图查找类似的东西,但我什至不知道它有什么功能...

谢谢!

您可以先通过查询

为您的id和days生成table
SELECT d1.id, generate_series(1, max(d1.days_since_start)) AS days_since_start
FROM days d1 JOIN days d2 ON d1.id = d2.id GROUP BY d1.id

(如果你需要从1100的所有数字,你可以替换表达式max(d1.days_since_start) 与数字 100)

然后与您的 table 一起加入。最终查询可能如下所示

WITH genDays AS
     (SELECT d1.id, generate_series(1, max(d1.days_since_start)) AS days_since_start
      FROM days d1 JOIN days d2 ON d1.id = d2.id GROUP BY d1.id)

SELECT coalesce(genDays.id, d3.id) AS id,
       d3.money_earned,
       coalesce(d3.days_since_start, genDays.days_since_start) AS days_since_start
FROM days d3 FULL JOIN genDays ON genDays.id = d3.id
                     AND genDays.days_since_start = d3.days_since_start

输出将根据您的需要

如果您需要用每个 ID 的最后一个非空值填充空值,那么您可以像这里一样修改查询

WITH genDays AS
     (SELECT d1.id as id, generate_series(1,  100) AS days_since_start
      FROM days d1 JOIN days d2 ON d1.id = d2.id GROUP BY d1.id)

SELECT coalesce(genDays.id, d3.id) AS id,
       coalesce(d3.money_earned, 
            (
                select d4.money_earned
                from days d4
                where d4.id = genDays.id
                  and d4.days_since_start < genDays.days_since_start
                order by d4.days_since_start desc
                limit 1
            )) as money_earned,
       coalesce(d3.days_since_start, genDays.days_since_start) AS days_since_start
FROM days d3 FULL JOIN genDays ON genDays.id = d3.id
                  AND genDays.days_since_start = d3.days_since_start