将 EAVT table 转换为 SCD 类型 2
Converting EAVT table into SCD type 2
经过大量研究和挑选,我仍然无法找到 good/clean 将实体属性值时间戳 table 转换为 scd 类型 2 维度的解决方案。
这是问题所在:
我有一个 CRM 源,它将所有历史记录存储在 EAVT 模型中(Entity/Attribute/Value of the attribute/valid_from/valid_to)。
因此,对于每个对象(公司、产品等),我都有一个 table 和关系模型中的当前状态,以及另一个包含所有属性的所有值更改的历史记录 table valid_from/valid_to 值本身有效性的列。
我希望能够将这两个 table 合并到一个 SCD table 中,每个属性有一个 Valid_To/Valid_From 和一个列。
举个例子:
公司有两个table:
- 公司现状:
company_id
name
number_of_employees
city
1
Company 1
500
Paris
2
Company 2
500
Paris
- 历史Table:
company_id
attribute
value
valid_from
valid_to
1
city
New York
01/01/2020
01/05/2022
1
city
Paris
01/05/2022
12/31/9999
1
number_of_employees
50
01/01/2021
01/01/2022
1
number_of_employees
100
01/01/2022
12/31/9999
我想要的结果如下:
company_id
name
city
number_of_employees
valid_from
valid_to
is_active
1
Company 1
New York
null
01/01/2020
01/01/2021
false
1
Company 1
New York
50
01/01/2021
01/01/2022
false
1
Company 1
New York
100
01/01/2022
01/01/2022
false
1
Company 1
Paris
100
01/05/2022
12/31/9999
true
因此,基于此示例,我们有一家公司于 2020 年 1 月 1 日成立,纽约作为城市,当时没有员工人数。
然后我们修改了我们的公司以增加 50 作为员工人数,这发生在 01/01/2021。
我们在01/01/2022再次修改我们的公司,将员工人数更改为100,只是在01/05/2021将公司所在城市从纽约更改为巴黎
这为我们提供了公司的 4 个州,因此我们的 SCD 应包含每个州一行或 4 行。
日期应计算为重叠,valid_from 应设置为从“历史”更改的属性的 valid_to table,valid_to 应设置为valid_from 从“历史”更改的属性 table。
为了增加任务的复杂性,假设我们有大约 120 个属性,但如果一家公司从未改变(刚刚创建并且仍然具有创建时的相同状态)那么它不会存在于“当前状态” " table。因此,在我们的示例中,公司 2 根本不存在于历史 table 中,必须从第一个 table 读取到 SCD(当前 table 和历史结果 [=] 之间的联合=69=]).好玩吧! :)
为了让您了解技术环境,CRM 是 hubspot,数据从 hubspot 复制到 BigQuery,报告工具是 Power BI。
我尝试在 Power BI 和 BigQuery 中使用数据透视,这是 EAV 模型 tables 的标准解决方案,但我在计算 valid/from valid/to 在结果 SCD 中。 (此处使用旋转的示例:https://dba.stackexchange.com/questions/20275/solutions-for-reporting-off-of-an-eav-structured-database)
我需要一个可以应用到多个 table 的过程(因为这个例子只针对公司,但我还有其他对象需要转换成 SCD)。
那么,在不陷入硬代码和性能问题的迷宫的情况下,将此 EAVT 数据转换为 SCD 的最佳方法是什么?以及如何动态计算valid_from/valid_to<
无论是 BigQuery 或 Power Query 还是仅仅是理论上的,任何解决方案、技巧、想法或只是简单的意见都将受到高度赞赏,因为这是我工作的公司采用整个数据文化的最后一步,并且如果我做不到,好吧……我的信誉将受到打击!所以请帮助一位迷路的 IT 专业人士! :D
太宽泛的问题 - 但无论如何,下面只是给你一个想法。显然它并没有涵盖所有情况 - 但希望你能进一步解决
select company_id, city, number_of_employees, min(day) valid_from, max(day) valid_to
from (
select * from (
select company_id, attribute, value, day
from history,
unnest(generate_date_array(date(valid_from), if(valid_to = '9999-12-31', date('2222-12-31'), date(valid_to)))) day
)
pivot (any_value(value) for attribute in ('city', 'number_of_employees'))
)
group by company_id, city, number_of_employees
如果应用于您问题中的示例数据
with history as (
select 1 company_id, 'city' attribute, 'New York' value, '2020-01-01' valid_from, '2022-01-05' valid_to union all
select 1, 'city', 'Paris', '2022-01-05', '2222-12-31' union all
select 1, 'number_of_employees', '50', '2021-01-01', '2022-01-01' union all
select 1, 'number_of_employees', '100', '2022-01-01', '2222-12-31'
)
输出是
经过大量研究和挑选,我仍然无法找到 good/clean 将实体属性值时间戳 table 转换为 scd 类型 2 维度的解决方案。
这是问题所在: 我有一个 CRM 源,它将所有历史记录存储在 EAVT 模型中(Entity/Attribute/Value of the attribute/valid_from/valid_to)。 因此,对于每个对象(公司、产品等),我都有一个 table 和关系模型中的当前状态,以及另一个包含所有属性的所有值更改的历史记录 table valid_from/valid_to 值本身有效性的列。
我希望能够将这两个 table 合并到一个 SCD table 中,每个属性有一个 Valid_To/Valid_From 和一个列。
举个例子: 公司有两个table:
- 公司现状:
company_id | name | number_of_employees | city |
---|---|---|---|
1 | Company 1 | 500 | Paris |
2 | Company 2 | 500 | Paris |
- 历史Table:
company_id | attribute | value | valid_from | valid_to |
---|---|---|---|---|
1 | city | New York | 01/01/2020 | 01/05/2022 |
1 | city | Paris | 01/05/2022 | 12/31/9999 |
1 | number_of_employees | 50 | 01/01/2021 | 01/01/2022 |
1 | number_of_employees | 100 | 01/01/2022 | 12/31/9999 |
我想要的结果如下:
company_id | name | city | number_of_employees | valid_from | valid_to | is_active |
---|---|---|---|---|---|---|
1 | Company 1 | New York | null | 01/01/2020 | 01/01/2021 | false |
1 | Company 1 | New York | 50 | 01/01/2021 | 01/01/2022 | false |
1 | Company 1 | New York | 100 | 01/01/2022 | 01/01/2022 | false |
1 | Company 1 | Paris | 100 | 01/05/2022 | 12/31/9999 | true |
因此,基于此示例,我们有一家公司于 2020 年 1 月 1 日成立,纽约作为城市,当时没有员工人数。 然后我们修改了我们的公司以增加 50 作为员工人数,这发生在 01/01/2021。 我们在01/01/2022再次修改我们的公司,将员工人数更改为100,只是在01/05/2021将公司所在城市从纽约更改为巴黎
这为我们提供了公司的 4 个州,因此我们的 SCD 应包含每个州一行或 4 行。 日期应计算为重叠,valid_from 应设置为从“历史”更改的属性的 valid_to table,valid_to 应设置为valid_from 从“历史”更改的属性 table。
为了增加任务的复杂性,假设我们有大约 120 个属性,但如果一家公司从未改变(刚刚创建并且仍然具有创建时的相同状态)那么它不会存在于“当前状态” " table。因此,在我们的示例中,公司 2 根本不存在于历史 table 中,必须从第一个 table 读取到 SCD(当前 table 和历史结果 [=] 之间的联合=69=]).好玩吧! :)
为了让您了解技术环境,CRM 是 hubspot,数据从 hubspot 复制到 BigQuery,报告工具是 Power BI。
我尝试在 Power BI 和 BigQuery 中使用数据透视,这是 EAV 模型 tables 的标准解决方案,但我在计算 valid/from valid/to 在结果 SCD 中。 (此处使用旋转的示例:https://dba.stackexchange.com/questions/20275/solutions-for-reporting-off-of-an-eav-structured-database)
我需要一个可以应用到多个 table 的过程(因为这个例子只针对公司,但我还有其他对象需要转换成 SCD)。 那么,在不陷入硬代码和性能问题的迷宫的情况下,将此 EAVT 数据转换为 SCD 的最佳方法是什么?以及如何动态计算valid_from/valid_to<
无论是 BigQuery 或 Power Query 还是仅仅是理论上的,任何解决方案、技巧、想法或只是简单的意见都将受到高度赞赏,因为这是我工作的公司采用整个数据文化的最后一步,并且如果我做不到,好吧……我的信誉将受到打击!所以请帮助一位迷路的 IT 专业人士! :D
太宽泛的问题 - 但无论如何,下面只是给你一个想法。显然它并没有涵盖所有情况 - 但希望你能进一步解决
select company_id, city, number_of_employees, min(day) valid_from, max(day) valid_to
from (
select * from (
select company_id, attribute, value, day
from history,
unnest(generate_date_array(date(valid_from), if(valid_to = '9999-12-31', date('2222-12-31'), date(valid_to)))) day
)
pivot (any_value(value) for attribute in ('city', 'number_of_employees'))
)
group by company_id, city, number_of_employees
如果应用于您问题中的示例数据
with history as (
select 1 company_id, 'city' attribute, 'New York' value, '2020-01-01' valid_from, '2022-01-05' valid_to union all
select 1, 'city', 'Paris', '2022-01-05', '2222-12-31' union all
select 1, 'number_of_employees', '50', '2021-01-01', '2022-01-01' union all
select 1, 'number_of_employees', '100', '2022-01-01', '2222-12-31'
)
输出是