Sql 将维度实体的历史期间合并为一个

Sql 将维度实体的历史期间合并为一个,sql,tsql,business-intelligence,dimension,Sql,Tsql,Business Intelligence,Dimension,我有一个缓慢变化的维度类型2,其行相同(除了开始日期和结束日期)。如何编写一个漂亮的SQL查询来合并相同且具有连接时间段的行 当前数据 +-------------+---------------------+--------------+------------+ | DimensionID | DimensionAttribute | RowStartDate | RowEndDate | +-------------+---------------------+-------------

我有一个缓慢变化的维度类型2,其行相同(除了开始日期和结束日期)。如何编写一个漂亮的SQL查询来合并相同且具有连接时间段的行

当前数据

+-------------+---------------------+--------------+------------+
| DimensionID | DimensionAttribute  | RowStartDate | RowEndDate |
+-------------+---------------------+--------------+------------+
|           1 | SomeValue           | 2019-01-01   | 2019-01-31 |
|           1 | SomeValue           | 2019-02-01   | 2019-02-28 |
|           1 | AnotherValue        | 2019-03-01   | 2019-03-31 |
|           1 | SomeValue           | 2019-04-01   | 2019-04-30 |
|           1 | SomeValue           | 2019-05-01   | 2019-05-31 |
|           2 | SomethingElse       | 2019-01-01   | 2019-01-31 |
|           2 | SomethingElse       | 2019-02-01   | 2019-02-28 |
|           2 | SomethingElse       | 2019-03-01   | 2019-03-31 |
|           2 | CompletelyDifferent | 2019-04-01   | 2019-04-30 |
|           2 | SomethingElse       | 2019-05-01   | 2019-05-31 |
+-------------+---------------------+--------------+------------+
结果

+-------------+---------------------+--------------+------------+
| DimensionID | DimensionAttribute  | RowStartDate | RowEndDate |
+-------------+---------------------+--------------+------------+
|           1 | SomeValue           | 2019-01-01   | 2019-02-28 |
|           1 | AnotherValue        | 2019-03-01   | 2019-03-31 |
|           1 | SomeValue           | 2019-04-01   | 2019-05-31 |
|           2 | SomethingElse       | 2019-01-01   | 2019-03-31 |
|           2 | CompletelyDifferent | 2019-04-01   | 2019-04-30 |
|           2 | SomethingElse       | 2019-05-01   | 2019-05-31 |
+-------------+---------------------+--------------+------------+

对于此版本的问题,我将使用
lag()
确定组的起始位置,然后使用累积和和和聚合:

select dimensionid, DimensionAttribute,
       min(row_start_date), max(row_end_date)
from (select t.*,
             sum(case when prev_red = dateadd(day, -1, row_start_date)
                      then 0 else 1
                 end) over (partition by dimensionid, DimensionAttribute order by row_start_date) as grp
      from (select t.*, 
                   lag(row_end_date) over (partition by dimensionid, DimensionAttribute order by row_start_date) as prev_red
            from t 
           ) t
     ) t
group by dimensionid, DimensionAttribute, grp;

特别是,这将识别行中的间隙。只有当行完全匹配时,它才会合并行——前一个结束日期是开始日期前一天。当然,这可以调整为允许1到2天的间隔或允许重叠。

搜索间隔和孤岛,有很多例子。试一试,如果你被卡住了,展示你的尝试。所以这不是免费的编码服务。当您尝试自己解决问题但失败时,我们很乐意帮助您,但您首先需要做出努力。谢谢。如果两个完全相同的行之间存在间隙,您将如何处理数据?在@Longluck,Stack Overflow用于询问编码/编程问题。人们在这里问问题的原因是他们自己试图解决问题,但失败了。询问“想法”的问题对于Stack Overflow来说是离题的,因为它不是一个讨论网站。因此,我和其他人将此视为“要求代码”的原因是,这正是如此,要求代码解决问题。这正是你得到的答案。@Larnu它说问题应该在哪里有代码?我是否可以添加我解决问题的失败尝试,当然?但在这种情况下,我认为这对理解这个问题没有任何价值。你一开始就攻击我,认为我有先入为主的想法,人们会为我工作。我想我事先什么都没试过,也没努力。事实上,我把我真正的问题从与我实际工作相关的所有东西中剥离出来,以便使问题尽可能简单明了。在这里提问的一部分是展示你的尝试。我根本没有攻击你。有一些期望和方法可以询问堆栈溢出,其中之一就是展示您的努力。这可能是代码,也可能是对你不理解的东西的研究和描述。然而,当用户利用空闲时间帮助你时,那些没有表现出努力的问题往往会导致很少的答案,或是被否决。因此,我们确实希望您尝试并展示您的努力。谢谢。我没有想过使用sum和window函数在数据集中创建单独的组。我工作得很有魅力:)