簡體   English   中英

SQL:將表(ID,[Datetime],[INT])更改為(ID,Start_DT,End_DT,[INT])

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

我有這種格式的舊數據:

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]
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 6-1-2012 6-2-2012 2

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

並不是

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

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

您需要更多業務規則來確定

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM