假设我有两个表,这些表包含成对的时间定向数据(日期,数据)。其中一个人持有我的日常开支,另一个人持有我的日常收入。日期表示该费用/收入率何时开始。
例如:如果我在收入表中有两个记录:(2020-01-01,50),(2020-02-14,100),这意味着在2020-01-01和2020-02-14之间每天的收入为50个单位,2020-02-14之后的收入为每天100个单位。费用也一样。
我想在postgres表中生成给定时间间隔的时间序列(可能使用time generate_series(date,date,interval)函数),其中一行如下所示:(天,收入,费用)
例如,如果我的收入表如下所示:
+------------+--------+
| date | income |
+------------+--------+
| 2020-02-12 | 50 |
| 2020-02-14 | 100 |
+------------+--------+
以及类似费用:
+------------+--------------+
| date | expenses |
+------------+--------------+
| 2020-02-12 | 70 |
| 2020-02-13 | 50 |
+------------+--------------+
我希望从2020-02-12到2020-02-15的时间间隔看起来像这样:
+------------+--------+--------------+
| day | income | expenses |
+------------+--------+--------------+
| 2020-02-12 | 50 | 70 |
| 2020-02-13 | 50 | 50 |
| 2020-02-14 | 100 | 50 |
| 2020-02-15 | 100 | 50 |
+------------+--------+--------------+
因此,以后我可以例如计算我的利润,亏损和其他统计数据。我该如何实现?
有点棘手。您可以在日期上单击full join
,但是您需要填补空白。 Postgres不支持窗口函数上的ignore nulls
,因此一种选择是使用条件总和来建立组,然后使用first_value()
:
select
date,
first_value(income) over(partition by grp_i order by date) income,
first_value(expense) over(partition by grp_e order by date) expense
from (
select
date,
i.income,
e.expense,
count(*) filter(where i.income is not null) over(order by date) grp_i,
count(*) filter(where e.expense is not null) over(order by date) grp_e
from incomes i
full join expenses e using(date)
) t
另一方面,您也可以从选定的日期开始(使用generate_series()
),然后将表带有left join
。其余逻辑保持不变:
select
date,
first_value(income) over(partition by grp_i order by date) income,
first_value(expense) over(partition by grp_e order by date) expense
from (
select
d.date,
i.income,
e.expense,
count(*) filter(where i.income is not null) over(order by d.date) grp_i,
count(*) filter(where e.expense is not null) over(order by d.date) grp_e
from generate_series(date '2020-02-12', date '2020-02-15', interval '1' day) d(date)
left join incomes i on i.date = d.date
left join expenses e on e.date = d.date
) t
order by date