使用版本 ID 缓慢更改维度类型 2
Slowly changing dimension Type 2 with Version ID
我正在尝试使用不同的 table 实现此功能,以便能够在最后获得历史报告。
第一次我想对我的历史 table 有一个基线信息。这里有一些信息
**EmployeeHistory:**
id Number OrgId AccountId VersionId Date
1 34343 1 1 1 2010-01-01
**OrganizationHistory:**
OrgId Name VersionId Date
1 Sales 1 2010-01-01
**AccountHistory:**
AccountId Name VersionId Date
1 ABC 1 2010-01-01
**Final Employee Report:**
id Number OrgId AccountId Date
1 34343 Sales ABC 2010-01-01
我正在使用 VersionId(在本例中等于 1)帮助我在特定时间检索数据。任何更改都会在 table 上插入记录并将 VersionId 增加 1 所以假设现在我更改了 AccountId 名称,我将在我的帐户 table:
上有一条新记录
AccountId Name VersionId Date
1 ABC 1 2010-01-01
1 ABB 2 2010-01-02
好的,现在我要更改员工编号
id Number OrgId AccountId VersionId Date
1 34343 1 1 1 2010-01-01
1 34355 1 1 2 2010-01-03
对于每个人 table 没问题,我可以很容易地按 Date 加上 VersionId 检索数据顺序,因为我可以在同一天进行很多更改。
我的问题是如何从我的 EmployeeHistory table 开始向下钻取 table 的其余部分来准确检索我的员工报告?通过 Versionid 是不可能的,因为 versionId 是独立的并且对于每个 table,按日期是不同的,因为我猜会很慢,如果我在同一天有很多变化,我应该添加最新的条件版本号。
有解决这个问题的想法或好的例子吗?
以下查询将为您提供在任何特定日期按 Number 的升序和 VersionId 的降序排序的员工变更
SELECT EH.*
FROM EmployeeHistory EH
INNER
JOIN (
SELECT OH.OrgId
, OH.Date
, MAX(OH.VersionId) AS VersionId
FROM OrganizationHistory OH
GROUP
BY OH.OrgId, OH.Date
) O
ON EH.OrgId = O.OrgId
AND EH.Date = O.Date
INNER
JOIN (
SELECT AH.AccountId
, AH.Date
, MAX(AH.VersionId) AS VersionId
FROM AccountHistory AH
GROUP
BY AH.AccountId
, AH.Date
) A
ON EH.AccountId = A.AccountId
AND EH.Date = A.Date
WHERE EH.Date = "2010-01-01"
ORDER
BY EH.Number ASC
,EH.VersionID DESC
账户的sub-query根据所有日期的VersionId获取账户(AccountId)的最新记录。组织的 sub-query 对组织也是如此。
希望这对您有所帮助..
在适当的维度模型中,您的维度行应该由代理键标识。您混淆了维度键、业务键和版本的概念,这就是您在建模时遇到问题的原因。
正如其他人指出的那样,您还遗漏了一个事实 table。您可能遇到一种称为 "factless fact" 的情况,即事实 table 仅用于建立维度之间的关系,并且没有记录事实的度量。
我认为你的模型应该是这样的:
employment_factless_fact (dim_emp_id, dim_org_id, dim_acc_id)
dim_employee (dim_emp_id,emp_id,...)
dim_organisation (dim_ord_id,org_id,org_name,from_date,to_date,...)
dim_account (dim_acc_id,acc_id,acc_name,from_date,to_date,...)
dim_x_id和x_id的区别在于dim_x_id是代理键,x_id是业务键。我的业务密钥永远不会改变,但每次我的某些事情(即姓名)发生变化时,我都会有不同的代理值。我只是用这个命名约定来说明模型,我不会在实践中推荐它。
我正在尝试使用不同的 table 实现此功能,以便能够在最后获得历史报告。
第一次我想对我的历史 table 有一个基线信息。这里有一些信息
**EmployeeHistory:**
id Number OrgId AccountId VersionId Date
1 34343 1 1 1 2010-01-01
**OrganizationHistory:**
OrgId Name VersionId Date
1 Sales 1 2010-01-01
**AccountHistory:**
AccountId Name VersionId Date
1 ABC 1 2010-01-01
**Final Employee Report:**
id Number OrgId AccountId Date
1 34343 Sales ABC 2010-01-01
我正在使用 VersionId(在本例中等于 1)帮助我在特定时间检索数据。任何更改都会在 table 上插入记录并将 VersionId 增加 1 所以假设现在我更改了 AccountId 名称,我将在我的帐户 table:
上有一条新记录AccountId Name VersionId Date
1 ABC 1 2010-01-01
1 ABB 2 2010-01-02
好的,现在我要更改员工编号
id Number OrgId AccountId VersionId Date
1 34343 1 1 1 2010-01-01
1 34355 1 1 2 2010-01-03
对于每个人 table 没问题,我可以很容易地按 Date 加上 VersionId 检索数据顺序,因为我可以在同一天进行很多更改。
我的问题是如何从我的 EmployeeHistory table 开始向下钻取 table 的其余部分来准确检索我的员工报告?通过 Versionid 是不可能的,因为 versionId 是独立的并且对于每个 table,按日期是不同的,因为我猜会很慢,如果我在同一天有很多变化,我应该添加最新的条件版本号。
有解决这个问题的想法或好的例子吗?
以下查询将为您提供在任何特定日期按 Number 的升序和 VersionId 的降序排序的员工变更
SELECT EH.*
FROM EmployeeHistory EH
INNER
JOIN (
SELECT OH.OrgId
, OH.Date
, MAX(OH.VersionId) AS VersionId
FROM OrganizationHistory OH
GROUP
BY OH.OrgId, OH.Date
) O
ON EH.OrgId = O.OrgId
AND EH.Date = O.Date
INNER
JOIN (
SELECT AH.AccountId
, AH.Date
, MAX(AH.VersionId) AS VersionId
FROM AccountHistory AH
GROUP
BY AH.AccountId
, AH.Date
) A
ON EH.AccountId = A.AccountId
AND EH.Date = A.Date
WHERE EH.Date = "2010-01-01"
ORDER
BY EH.Number ASC
,EH.VersionID DESC
账户的sub-query根据所有日期的VersionId获取账户(AccountId)的最新记录。组织的 sub-query 对组织也是如此。
希望这对您有所帮助..
在适当的维度模型中,您的维度行应该由代理键标识。您混淆了维度键、业务键和版本的概念,这就是您在建模时遇到问题的原因。
正如其他人指出的那样,您还遗漏了一个事实 table。您可能遇到一种称为 "factless fact" 的情况,即事实 table 仅用于建立维度之间的关系,并且没有记录事实的度量。
我认为你的模型应该是这样的:
employment_factless_fact (dim_emp_id, dim_org_id, dim_acc_id)
dim_employee (dim_emp_id,emp_id,...)
dim_organisation (dim_ord_id,org_id,org_name,from_date,to_date,...)
dim_account (dim_acc_id,acc_id,acc_name,from_date,to_date,...)
dim_x_id和x_id的区别在于dim_x_id是代理键,x_id是业务键。我的业务密钥永远不会改变,但每次我的某些事情(即姓名)发生变化时,我都会有不同的代理值。我只是用这个命名约定来说明模型,我不会在实践中推荐它。