【问题标题】:Selecting from a slowly changing dimension type II从渐变维度类型 II 中选择
【发布时间】:2012-04-13 21:38:54
【问题描述】:

我在选择缓慢变化的维度类型 II 时遇到问题。我希望选择员工技能认证的实际长度,以便我可以在报告中显示他的认证的开始和结束。你会怎么做呢?下面我包含了员工“80844”的记录图像,记录下方是预期结果。

我正在使用 Microsoft SQL Server 2008 R2。

【问题讨论】:

  • 您使用的是什么类型的数据库?
  • 我使用的是 Microsoft SQL Server 2008 R2。
  • 我不明白结果是如何确定的。为什么结果的第一行是结束日期 2012-04-01?
  • @tombom,结果中的第一行将第 2,3,4 行合并到结果中的第一行,因为它们的日期间隔是连续的。
  • 请问,到底为什么要插入这些行?为什么不将它存储在一行中,从 1900-01-01 开始,到 2012-04-01 结束?也许你应该在你的 ETL 上工作。当没有真正的变化时,保持该行不变。标记结束日期为 NULL 的最新行。

标签: sql type-2-dimension


【解决方案1】:

感谢您提出有趣的问题。这是众所周知的“差距和岛屿”问题。你可以阅读更多关于它的信息there

您的案例解决方案可能如下所示:

    create table #tmp 
       (
         dimEmployeeID int not null,
         EmployeeNumber int not null,
         Start datetime not null,
         [End] datetime not null,
         SkillID int not null
       )


   insert into #tmp values
     (386 , 80844, '1900-01-01', '2012-02-28', 14),
     (1172, 80844, '2012-02-29', '2012-02-29', 14),
     (1173, 80844, '2012-03-01', '2012-04-01', 14),
     (1175, 80844, '2012-04-06', '2012-04-12', 14),
     (1176, 80844, '2012-04-13', '2012-04-21', 14),
     (1172, 80844, '2012-02-29', '2012-02-29', 87),
     (1173, 80844, '2012-03-01', '2012-04-01', 87),
     (1174, 80844, '2012-04-02', '2012-04-05', 87),
     (1175, 80844, '2012-04-06', '2012-04-12', 87)

   ;with StartingPoints as
   (
     SELECT EmployeeNumber, SkillID, Start, ROW_NUMBER() OVER(partition by EmployeeNumber,    SkillID order by Start asc) AS rn
     FROM #tmp AS A
     WHERE NOT EXISTS
       (
         SELECT 1
         FROM #tmp AS B
         WHERE 
           A.EmployeeNumber = B.EmployeeNumber
           and A.SkillID = B.SkillID
           and A.Start - 1 = B.[End]
        )
   ),
   EndingPoints AS
   (
     SELECT EmployeeNumber, SkillID, [End], ROW_NUMBER() OVER(partition by EmployeeNumber,    SkillID order by Start asc) AS rn
     FROM #tmp AS A
     WHERE NOT EXISTS
       (
         SELECT 1
         FROM #tmp AS B
         WHERE 
           A.EmployeeNumber = B.EmployeeNumber
           and A.SkillID = B.SkillID
           and A.[End] + 1 = B.Start
        )
   )
   SELECT S.EmployeeNumber, S.SkillID, S.Start, E.[End]
   FROM StartingPoints AS S
     JOIN EndingPoints AS E
   ON 
     S.EmployeeNumber = E.EmployeeNumber
     and S.SkillID = E.SkillID
     and S.rn = E.rn

【讨论】:

  • 谢谢,太好了。这正是我正在寻找的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-14
  • 1970-01-01
  • 2014-08-11
  • 2013-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多