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:元の日時が1つありますが、実際のデータでは時間の部分が異なります
  • 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 です...t-sql ではなく、group by ステートメントを id,num に変更する必要があると思います。

追加:

であることをどのように知っていますか

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

1時間ほど前にトップに投稿したのかな…?そして、それはぎこちない(そしてずさんな)と言いました...私のものはひどいので、誰かがより良い答えを持っているかどうか疑問に思っていました。しかし、より良いビジネス ルールが必要で、特定の状況を処理する方法を知る必要があると人々が投稿し続ける理由がわかりません。このコードは、 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 に答える