即使没有数据也能获取每个 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
(如果你需要从1到100的所有数字,你可以替换表达式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
我有一个 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生成tableSELECT 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
(如果你需要从1到100的所有数字,你可以替换表达式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