0

我有一些这种格式的旧数据:

ID    DT          NUM 
1     6-1-2012    2
1     6-2-2012    2
1     6-3-2012    4
1     6-4-2012    4
1     6-5-2012    8
1     6-6-2012    8
1     6-7-2012    8
1     6-8-2012    16
1     6-9-2012    2
1     6-10-2012   2

我需要它看起来像这样:

ID    START_DT    END_DT      NUM
1     6-1-2012    6-2-2012    2 
1     6-3-2012    6-4-2012    4
1     6-5-2012    6-7-2012    8 
1     6-8-2012    6-8-2012    16
1     6-9-2012    6-10-2012   2

这是我可以快速提出的数据的最佳示例。如果我不小心在其中包含了一些误解,我很想澄清一下。

规则:

  • ID:这确实发生了变化,它最终会被分组,为了让事情变得简单,在我的例子中也是一样的
  • DT:我得到一个原始日期时间,在真实数据中时间部分确实不同
  • START_DT、END_DT:我需要将这些列从原始 DT 中取出
  • NUM:这只是一个可以更改的整数,并且可以根据 ID 重新出现

编辑:这很尴尬.....(必须有更好的答案)......我还没有在很多条件下测试过这个,但从一开始它看起来还不错......并且不得不手动找到并替换所有字段名称(友善)

select * from (
    select  *,row_number() over (partition by if_id, [z.num] order by if_id, [y.num]) as rownum

    from (
            select  y.id,
                    y.dt as [y.dt], 
                    z.dt as [z.dt],    
                    y.num

            from    #temp as y 

                    outer apply (select top 1 id, dt, num

                                    from    #temp as x 

                                    where   x.id = y.id and 
                                            x.dt > y.dtand 
                                            x.num <> y.num

                                    order by x.dt asc) as z   ) as x ) as k
where rownum=1
order by [y.dt]
4

2 回答 2

2
select id,min(dt) as start_date, max(dt) as end_date, num
from whatevertablename_helps_if_you_supply_these_when_asking_for_code
group by 1,4

也可以将其作为获取最小值的子查询和获取最大值的子查询来执行,但不要认为您需要在此处执行此操作。

我的答案是 Postgres ...我认为您需要将 group by 语句更改为 id,num 而不是在 t-sql 中。

添加:

你怎么知道它是

1 2012 年 6 月 1 日 2012 年 6 月 2 日 2

1 2012 年 6 月 9 日 2012 年 6 月 10 日 2

并不是

1 2012 年 6 月 1 日 2012 年 6 月 10 日 2

1 2012 年 6 月 2 日 2012 年 6 月 9 日 2

您需要更多的业务规则来确定

于 2012-06-21T16:57:05.260 回答
0
select id, [y.dt] as start_dt, [z.dt] as end_dt, num from (
        select  *,row_number() over (partition by id, [z.dt] order by id, [y.dt]) as rownum

        from (
                select  y.id,
                        y.dt as [y.dt], 
                        z.dt as [z.dt],    
                        y.num

                from    #temp as y 

                        outer apply (select top 1 id, dt, num

                                        from    #temp as x 

                                        where   x.id = y.id and 
                                                x.dt > y.dt and 
                                                x.num <> y.num

                                        order by x.dt asc) as z   ) as x ) as k
where rownum=1
order by id, [y.dt]

这给了我们......(使用不同的数据)

id     start_dt                 end_dt                         num
6      2011-10-01 00:00:00.000  2012-01-18 00:00:00.000        896
6      2012-01-18 00:00:00.000  2012-02-01 00:00:00.000        864
6      2012-02-01 00:00:00.000  NULL                           896

大约一个小时前我把它贴在了顶部,也许......?并说这很尴尬(而且草率)......我想知道是否有人有更好的答案,因为我的很烂。但我不明白为什么人们不断发布他们需要更好的业务规则并且需要知道如何处理某些情况的帖子。这段代码完全符合我的要求,除了 end_dt 是新 num 的日期时间,而不是当前 num 的最后一次出现......但我可以使用它。总比没有好。(对不起,沮丧)。

业务规则:数据已经存在。它应该显示逻辑范围。我需要 num 的 start_dt 和 end_dt...当 NUM = Y 时,开始日期是 NUM 从 X 变为 Y 的时间,结束日期是 Y 变为 Z 的时间。我不能给你比我自己拥有的更多这一切……这些规则对我来说已经足够了……??

好的,相同的数据:

 id      start_dt   end_dt       num
 1       6-1-2012   6-3-2012    2
 1       6-3-2012   6-5-2012    4
 1       6-5-2012   6-8-2012    8
 1       6-8-2012   6-9-2012    16
 1       6-9-2012   NULL        2
于 2012-06-21T18:38:39.733 回答