简体   繁体   English

SQL:将表(ID,[Datetime],[INT])更改为(ID,Start_DT,End_DT,[INT])

[英]SQL: changing table (ID, [Datetime], [INT]) to (ID, Start_DT, End_DT, [INT])

I have some old data in this format: 我有这种格式的旧数据:

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

And I need it to look like this: 我需要它看起来像这样:

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

This is the best example of the data that I could quickly come up with. 这是我可以快速提出的数据的最佳示例。 I would love to clarify if I accidently included some misunderstanding(s) in it. 如果我意外地包含一些误解,我想澄清一下。

The Rules: 规则:

  • ID: this does change, it will be grouped on eventually, to make things easy it says the same in my example ID:这确实会发生变化,它会最终分组,为了让事情变得简单,在我的例子中也是如此
  • DT: I get one orginal datetime, in the real data the time part does vary DT:我得到一个原始日期时间,在实际数据中时间部分确实变化
  • START_DT, END_DT: I need to get these columns out of the original DT START_DT,END_DT:我需要从原始DT中获取这些列
  • NUM: this is just an integer that changes and can reoccur per ID NUM:这只是一个更改的整数, 可以重新发送每个ID

EDIT: this is very awkward..... (there MUST be a better answer)... i haven't tested this yet with a lot of conditions but it looks okay from the start.... and had to manually find and replace all the field names (be kind) 编辑:这是非常尴尬..... (必须有一个更好的答案)... 我还没有测试这个有很多条件但它从一开始看起来没问题....并且不得不手动查找并替换所有字段名称(善意)

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]
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

It's also possible to do it as a subquery to get the min and a subquery to get the max, but don't think you need to do that here. 它也可以作为子查询来获取最小值和子查询以获得最大值,但不要认为你需要在这里做到这一点。

My answer is Postgres...I think you'll need to change the group by statement to be id,num instead in t-sql. 我的回答是Postgres ...我认为你需要将group by语句更改为id,num而不是t-sql。

Adding: 添加:

How do you know that it is 你怎么知道它是

1 6-1-2012 6-2-2012 2 1 6-1-2012 6-2-2012 2

1 6-9-2012 6-10-2012 2 1 6-9-2012 6-10-2012 2

and not 并不是

1 6-1-2012 6-10-2012 2 1 6-1-2012 6-10-2012 2

1 6-2-2012 6-9-2012 2 1 6-2-2012 6-9-2012 2

You need more business rules to determine that 您需要更多业务规则来确定

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]

and that gives us... (with different data) 这给了我们......(有不同的数据)

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

i posted that up at the top about an hour ago maybe...? 大约一个小时前我在顶部发布了这个...也许......? and said it was awkward (and sloppy)... i was wondering if anyone has a better answer because mine sucks. 并说这很尴尬(而且草率)......我想知道是否有人有更好的答案,因为我很糟糕。 but i don't understand why people keep posting that they need better business rules and need to know how to handle certain situations. 但我不明白为什么人们不断发布他们需要更好的业务规则并且需要知道如何处理某些情况。 this code does exactly what i want except end_dt is the datetime of the new num and not the last occurance of the current num.... but I can work with that. 这段代码正是我想要的,除了end_dt是新num的日期时间而不是当前num的最后一次出现....但我可以使用它。 It is better than nothing. 总比没有好。 (sorry, frustrated). (抱歉,沮丧)。

Business rule: the data is already there. 业务规则:数据已存在。 it should show the logical span. 它应该显示逻辑跨度。 I need the start_dt and end_dt for num... When NUM = Y, the Start date is when NUM changes from X to Y and the End Date is when Y changes to Z. I can't give you more than I have myself with all of this... These rules were enough for me...?? 我需要num_的start_dt和end_dt ...... 当NUM = Y时,开始日期是NUM从X变为Y而结束日期是Y变为Z.我不能给你超过我自己所有这些......这些规则对我来说已经足够了......?

ok, same data: 好的,相同的数据:

 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 SQL (Oracle) 查询具有最大日期的记录,仅当 end_dt 有值时 - SQL (Oracle) to query for record with max date, only if the end_dt has a value 如何排除在同一 start_dt 上的数据中创建循环的记录? - How to exclude record which creates cycle in data on same start_dt? 仅当 first_stamp 位于 start_dt 的窗口之间时员工计数 - Count of Employee only when first_stamp is between a window of start_dt 根据下一个创建的记录创建日期,更新为空的end_dt列 - update a end_dt column which is null based on next created record created date 我正在尝试将bacclaim表中的loss_dt从其他表bactrans更新为对Claim_id的其他表bactrans,其中loss_Dt&gt; trans_dt - I am trying to update loss_dt in bacclaim table to trans_dt from other table bactrans on claim_id where loss_Dt >trans_dt 错误:将SQL表ID转换为GUID时,int与uniqueidentifier不兼容 - Error: int is incompatible with uniqueidentifier when converted SQL table ID to GUID SQL在没有ID的同一张表上选择int更新 - SQL select int update on same table without ID SQL将INT转换为datetime - SQL convert INT to datetime 将 INT 转换为 DATETIME (SQL) - Convert INT to DATETIME (SQL) SQL int转换为日期时间的字符串 - SQL int to string to datetime
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM