如何通过分组和排序在 PostgreSQL 中填充空值
How to fill null values in PostgreSQL with grouping and ordering
假设我有以下数据:
+---------------------+---------+---------------------+
| date | tokenId | last_price |
|---------------------+---------+---------------------|
| 2021-07-01 00:00:00 | 1 | <null> |
| 2021-08-01 00:00:00 | 1 | 5.0 |
| 2021-09-01 00:00:00 | 1 | <null> |
| 2021-10-01 00:00:00 | 1 | <null> |
| 2021-11-01 00:00:00 | 1 | 4.6000000000000005 |
| 2021-12-01 00:00:00 | 1 | <null> |
| 2022-01-01 00:00:00 | 1 | <null> |
| 2022-02-01 00:00:00 | 1 | <null> |
| 2022-03-01 00:00:00 | 1 | <null> |
| 2022-04-01 00:00:00 | 1 | <null> |
| 2022-05-01 00:00:00 | 1 | <null> |
| 2021-07-01 00:00:00 | 18 | 0.09200000000000001 |
| 2021-08-01 00:00:00 | 18 | <null> |
| 2021-09-01 00:00:00 | 18 | <null> |
| 2021-10-01 00:00:00 | 18 | <null> |
| 2021-11-01 00:00:00 | 18 | 7.6000000000000005 |
| 2021-12-01 00:00:00 | 18 | <null> |
| 2022-01-01 00:00:00 | 18 | 15.200000000000001 |
| 2022-02-01 00:00:00 | 18 | <null> |
| 2022-03-01 00:00:00 | 18 | <null> |
| 2022-04-01 00:00:00 | 18 | <null> |
| 2022-05-01 00:00:00 | 18 | <null> |
+---------------------+---------+---------------------+
我怎样才能像这样用前几行中每个代币的最后价格填充空行:
+---------------------+---------+---------------------+
| date | tokenId | last_price |
|---------------------+---------+---------------------|
| 2021-07-01 00:00:00 | 1 | <null> |
| 2021-08-01 00:00:00 | 1 | 5.0 |
| 2021-09-01 00:00:00 | 1 | 5.0 |
| 2021-10-01 00:00:00 | 1 | 5.0 |
| 2021-11-01 00:00:00 | 1 | 4.6000000000000005 |
| 2021-12-01 00:00:00 | 1 | 4.6000000000000005 |
| 2022-01-01 00:00:00 | 1 | 4.6000000000000005 |
| 2022-02-01 00:00:00 | 1 | 4.6000000000000005 |
| 2022-03-01 00:00:00 | 1 | 4.6000000000000005 |
| 2022-04-01 00:00:00 | 1 | 4.6000000000000005 |
| 2022-05-01 00:00:00 | 1 | 4.6000000000000005 |
| 2021-07-01 00:00:00 | 18 | 0.09200000000000001 |
| 2021-08-01 00:00:00 | 18 | 0.09200000000000001 |
| 2021-09-01 00:00:00 | 18 | 0.09200000000000001 |
| 2021-10-01 00:00:00 | 18 | 0.09200000000000001 |
| 2021-11-01 00:00:00 | 18 | 7.6000000000000005 |
| 2021-12-01 00:00:00 | 18 | 7.6000000000000005 |
| 2022-01-01 00:00:00 | 18 | 15.200000000000001 |
| 2022-02-01 00:00:00 | 18 | 15.200000000000001 |
| 2022-03-01 00:00:00 | 18 | 15.200000000000001 |
| 2022-04-01 00:00:00 | 18 | 15.200000000000001 |
| 2022-05-01 00:00:00 | 18 | 15.200000000000001 |
+---------------------+---------+---------------------+
我找到了关于类似问题 here 的一些很好的答案,但我不明白如何通过 tokenId 字段进行额外分组来使用它。
一个可能的解决方案是:
SELECT a_date, tokenId, last_price,
(SELECT last_price
FROM A_TABLE
WHERE a_date = (SELECT MAX(a_date)
FROM A_TABLE AS A
WHERE A.a_date <= T.a_date AND last_price IS NOT NULL))
FROM A_TABLE AS T
其他一些使用窗口函数
你可以使用横向。即:
select t1.date, t1.tokenid, coalesce(t1.last_price, p.last_price) last_price
from myTable t1
left join lateral(select last_price
from myTable t2
where t1.tokenId = t2.tokenId and t1.date > t2.date
and t2.last_price is not null
order by t2.date desc
limit 1) p on true
order by t1.tokenId, t1.date;
假设我有以下数据:
+---------------------+---------+---------------------+
| date | tokenId | last_price |
|---------------------+---------+---------------------|
| 2021-07-01 00:00:00 | 1 | <null> |
| 2021-08-01 00:00:00 | 1 | 5.0 |
| 2021-09-01 00:00:00 | 1 | <null> |
| 2021-10-01 00:00:00 | 1 | <null> |
| 2021-11-01 00:00:00 | 1 | 4.6000000000000005 |
| 2021-12-01 00:00:00 | 1 | <null> |
| 2022-01-01 00:00:00 | 1 | <null> |
| 2022-02-01 00:00:00 | 1 | <null> |
| 2022-03-01 00:00:00 | 1 | <null> |
| 2022-04-01 00:00:00 | 1 | <null> |
| 2022-05-01 00:00:00 | 1 | <null> |
| 2021-07-01 00:00:00 | 18 | 0.09200000000000001 |
| 2021-08-01 00:00:00 | 18 | <null> |
| 2021-09-01 00:00:00 | 18 | <null> |
| 2021-10-01 00:00:00 | 18 | <null> |
| 2021-11-01 00:00:00 | 18 | 7.6000000000000005 |
| 2021-12-01 00:00:00 | 18 | <null> |
| 2022-01-01 00:00:00 | 18 | 15.200000000000001 |
| 2022-02-01 00:00:00 | 18 | <null> |
| 2022-03-01 00:00:00 | 18 | <null> |
| 2022-04-01 00:00:00 | 18 | <null> |
| 2022-05-01 00:00:00 | 18 | <null> |
+---------------------+---------+---------------------+
我怎样才能像这样用前几行中每个代币的最后价格填充空行:
+---------------------+---------+---------------------+
| date | tokenId | last_price |
|---------------------+---------+---------------------|
| 2021-07-01 00:00:00 | 1 | <null> |
| 2021-08-01 00:00:00 | 1 | 5.0 |
| 2021-09-01 00:00:00 | 1 | 5.0 |
| 2021-10-01 00:00:00 | 1 | 5.0 |
| 2021-11-01 00:00:00 | 1 | 4.6000000000000005 |
| 2021-12-01 00:00:00 | 1 | 4.6000000000000005 |
| 2022-01-01 00:00:00 | 1 | 4.6000000000000005 |
| 2022-02-01 00:00:00 | 1 | 4.6000000000000005 |
| 2022-03-01 00:00:00 | 1 | 4.6000000000000005 |
| 2022-04-01 00:00:00 | 1 | 4.6000000000000005 |
| 2022-05-01 00:00:00 | 1 | 4.6000000000000005 |
| 2021-07-01 00:00:00 | 18 | 0.09200000000000001 |
| 2021-08-01 00:00:00 | 18 | 0.09200000000000001 |
| 2021-09-01 00:00:00 | 18 | 0.09200000000000001 |
| 2021-10-01 00:00:00 | 18 | 0.09200000000000001 |
| 2021-11-01 00:00:00 | 18 | 7.6000000000000005 |
| 2021-12-01 00:00:00 | 18 | 7.6000000000000005 |
| 2022-01-01 00:00:00 | 18 | 15.200000000000001 |
| 2022-02-01 00:00:00 | 18 | 15.200000000000001 |
| 2022-03-01 00:00:00 | 18 | 15.200000000000001 |
| 2022-04-01 00:00:00 | 18 | 15.200000000000001 |
| 2022-05-01 00:00:00 | 18 | 15.200000000000001 |
+---------------------+---------+---------------------+
我找到了关于类似问题 here 的一些很好的答案,但我不明白如何通过 tokenId 字段进行额外分组来使用它。
一个可能的解决方案是:
SELECT a_date, tokenId, last_price,
(SELECT last_price
FROM A_TABLE
WHERE a_date = (SELECT MAX(a_date)
FROM A_TABLE AS A
WHERE A.a_date <= T.a_date AND last_price IS NOT NULL))
FROM A_TABLE AS T
其他一些使用窗口函数
你可以使用横向。即:
select t1.date, t1.tokenid, coalesce(t1.last_price, p.last_price) last_price
from myTable t1
left join lateral(select last_price
from myTable t2
where t1.tokenId = t2.tokenId and t1.date > t2.date
and t2.last_price is not null
order by t2.date desc
limit 1) p on true
order by t1.tokenId, t1.date;