如何从三个独立的 table 构建事件 table,显示随时间的增量变化?
How do I build an events table from three separate tables showing incremental change over time?
我正在尝试构建一个数据集,以显示某些产品属性随时间的增量变化。数据在 AWS Athena 中的三个独立 table 中,每个存储不同的属性,并且可以在不同时间独立更新。 tbl1
可以连接到 tbl2
,tbl2
可以连接到 tbl3
。 table 之间始终存在一对一的关系,因此 tbl1.id=1
只会与 tbl2.id=2
相关,而 tbl2.id=2
只会与 tbl3.id=3
相关这个例子:
tbl1
| id | updated_at | bool |
| 1 | 2019-09-10 06:00 | True |
| 1 | 2020-08-05 10:00 | False |
| 1 | 2020-09-03 15:00 | True |
tbl2
| id | tbl1_id | updated_at | desc |
| 2 | 1 | 2019-09-10 06:00 | thing 1 |
tbl3
| id | tbl2_id | updated_at | value |
| 3 | 2 | 2019-09-10 06:00 | 100 |
| 3 | 2 | 2019-09-19 09:00 | 50 |
| 3 | 2 | 2019-12-02 11:00 | 20 |
我正在尝试编写一个查询,将这些数据连接成一个 table,并且每个增量更新都有一行。从上面的 tables 开始,在 2019-09-10 上进行了初始插入,然后在 tbl1
和 tbl3
中进行了其他四项更改,因此它最终应该变成五行,如下所示:
| tbl1_id | tbl1_updated_at | bool | tbl2_id | tbl2_updated_at | desc | tbl3_id | tbl3_updated_at | value |
| 1 | 2019-09-10 06:00 | True | 2 | 2019-09-10 06:00 | thing1 | 3 | 2019-09-10 06:00 | 100 |
| 1 | 2019-09-10 06:00 | True | 2 | 2019-09-10 06:00 | thing1 | 3 | 2019-09-19 09:00 | 50 |
| 1 | 2019-09-10 06:00 | True | 2 | 2019-09-10 06:00 | thing1 | 3 | 2019-12-02 11:00 | 20 |
| 1 | 2020-08-05 10:00 | False | 2 | 2019-09-10 06:00 | thing1 | 3 | 2019-12-02 11:00 | 20 |
| 1 | 2020-09-03 15:00 | True | 2 | 2019-09-10 06:00 | thing1 | 3 | 2019-12-02 11:00 | 20 |
我的想法是将所有内容连接在一起并使用一些 WHERE
子句,例如:
select
*
from
tbl1
left join tbl2 on tbl1.id = tbl2.tbl1_id
left join tbl3 on tbl2.id = tbl3.tbl2_id
where
???
但无法让它工作,也不确定这是否有效。也许有某种 window 函数可以做到这一点?感觉应该可以在 SQL 中执行此操作,但经过两天的尝试后,我完全不知道该怎么做!
这很复杂。如果您在所有表中都有 tbl1
id,会更简单。
无论如何,我们的想法是 union all
列连同 tbl1
id 和 updated_at
。然后聚合,所以每个 id
和 date
.
有一行
最后,使用 last_value()
和 ignore nulls
选项来获取填充的最新值:
with t as (
select id, updated_at, max(bool) as bool, max(descr) as descr, max(value) as value
from (select tbl1.id, tbl1.updated_at, tbl1.bool, null as descr, null as value
from tbl1
union all
select tbl2.tbl1_id, tbl2.updated_at, null, tbl2.descr, null
from tbl2
union all
select tbl2.tbl1_id, tbl2.updated_at, null, null, tbl3.value
from tbl2 join
tbl3
on tbl2.id = tbl3.tbl2_id
) t
group by id, updated_at
)
select id, updated_at,
last_value(bool ignore nulls) over (partition by id order by updated_at) as bool,
last_value(descr ignore nulls) over (partition by id order by updated_at) as descr,
last_value(value ignore nulls) over (partition by id order by updated_at) as value
from t;
我正在尝试构建一个数据集,以显示某些产品属性随时间的增量变化。数据在 AWS Athena 中的三个独立 table 中,每个存储不同的属性,并且可以在不同时间独立更新。 tbl1
可以连接到 tbl2
,tbl2
可以连接到 tbl3
。 table 之间始终存在一对一的关系,因此 tbl1.id=1
只会与 tbl2.id=2
相关,而 tbl2.id=2
只会与 tbl3.id=3
相关这个例子:
tbl1
| id | updated_at | bool |
| 1 | 2019-09-10 06:00 | True |
| 1 | 2020-08-05 10:00 | False |
| 1 | 2020-09-03 15:00 | True |
tbl2
| id | tbl1_id | updated_at | desc |
| 2 | 1 | 2019-09-10 06:00 | thing 1 |
tbl3
| id | tbl2_id | updated_at | value |
| 3 | 2 | 2019-09-10 06:00 | 100 |
| 3 | 2 | 2019-09-19 09:00 | 50 |
| 3 | 2 | 2019-12-02 11:00 | 20 |
我正在尝试编写一个查询,将这些数据连接成一个 table,并且每个增量更新都有一行。从上面的 tables 开始,在 2019-09-10 上进行了初始插入,然后在 tbl1
和 tbl3
中进行了其他四项更改,因此它最终应该变成五行,如下所示:
| tbl1_id | tbl1_updated_at | bool | tbl2_id | tbl2_updated_at | desc | tbl3_id | tbl3_updated_at | value |
| 1 | 2019-09-10 06:00 | True | 2 | 2019-09-10 06:00 | thing1 | 3 | 2019-09-10 06:00 | 100 |
| 1 | 2019-09-10 06:00 | True | 2 | 2019-09-10 06:00 | thing1 | 3 | 2019-09-19 09:00 | 50 |
| 1 | 2019-09-10 06:00 | True | 2 | 2019-09-10 06:00 | thing1 | 3 | 2019-12-02 11:00 | 20 |
| 1 | 2020-08-05 10:00 | False | 2 | 2019-09-10 06:00 | thing1 | 3 | 2019-12-02 11:00 | 20 |
| 1 | 2020-09-03 15:00 | True | 2 | 2019-09-10 06:00 | thing1 | 3 | 2019-12-02 11:00 | 20 |
我的想法是将所有内容连接在一起并使用一些 WHERE
子句,例如:
select
*
from
tbl1
left join tbl2 on tbl1.id = tbl2.tbl1_id
left join tbl3 on tbl2.id = tbl3.tbl2_id
where
???
但无法让它工作,也不确定这是否有效。也许有某种 window 函数可以做到这一点?感觉应该可以在 SQL 中执行此操作,但经过两天的尝试后,我完全不知道该怎么做!
这很复杂。如果您在所有表中都有 tbl1
id,会更简单。
无论如何,我们的想法是 union all
列连同 tbl1
id 和 updated_at
。然后聚合,所以每个 id
和 date
.
最后,使用 last_value()
和 ignore nulls
选项来获取填充的最新值:
with t as (
select id, updated_at, max(bool) as bool, max(descr) as descr, max(value) as value
from (select tbl1.id, tbl1.updated_at, tbl1.bool, null as descr, null as value
from tbl1
union all
select tbl2.tbl1_id, tbl2.updated_at, null, tbl2.descr, null
from tbl2
union all
select tbl2.tbl1_id, tbl2.updated_at, null, null, tbl3.value
from tbl2 join
tbl3
on tbl2.id = tbl3.tbl2_id
) t
group by id, updated_at
)
select id, updated_at,
last_value(bool ignore nulls) over (partition by id order by updated_at) as bool,
last_value(descr ignore nulls) over (partition by id order by updated_at) as descr,
last_value(value ignore nulls) over (partition by id order by updated_at) as value
from t;