2

この表を考えると:

代替テキスト

ID_Numberの各グループの各status_date間のdatediffを日数で取得するにはどうすればよいですか?つまり、ID_Numberが与えられた各ステータスの経過日数を見つける必要があります。

知っておくべきいくつかのこと:

  • すべてのID_Numberには、各ID_Numberの最も早い日付であるreceived_dateがあります(ただし、アプリは強制しません)
  • ID_Numberごとに、ID_Numberにその特定のステータスが与えられた日付である対応するstatus_dateを持つステータスがあります。
  • ステータス列は、必ずしも毎回同じ順序になるとは限りません(アプリは強制しません)
  • すべてのID_Numberにはclosed_dateがあり、これは最新の日付である必要があります(ただし、アプリは強制しません)

出力例:ID_Number 2001の場合、最初の日付(received_date)は2009-05-02であり、次に遭遇する日付のステータスは「オープン」で2009-05-02であるため、経過日数は0です。次に遭遇する日付は2009-05-10で、ステータスは「投資」であり、経過日数は前の日付から数えて8日です。次に遭遇する日付は2009-07-11で、経過日数は前の日付から数えて62日です。

追加するために編集:

経過日数をこのテーブル/ビューの列として表示することはできますか?また、これがSQLServer2000であることを追加するのを忘れました。

4

3 に答える 3

2

私が理解しているのは、closed_dateまでは、同じIDの最初のstatus_dateと次のstatus_dateの違いなどが必要だということです。

これはSQL2005以降でのみ機能します。

;with test as (
    select 
        key,
        id_number,
        status,
        received_date,
        status_date,
        closed_date,
        row_number() over (partition by id order by status_date, key ) as rownum
    from @test
    )
select 
    t1.key,
    t1.id_number,
    t1.status,
    t1.status_date,
    t1.received_date,
    t1.closed_date,
    datediff(d, case when t1.rownum = 1 
                then t1.received_date
                else    
                    case when t2.status_date is null 
                        then t1.closed_date 
                        else t2.status_date 
                    end
            end,
            t1.status_date
         ) as days
from test t1
left outer join test t2
on t1.id = t2.id
    and t2.rownum = t1.rownum - 1

このソリューションはSQL2000で機能しますが、パフォーマンスがどれほど優れているかはわかりません。

select *,
    datediff(d,
        case when prev_date is null
            then closed_date
            else prev_date
        end,
        status_date )
from ( 
    select *,
        isnull( ( select top 1 t2.status_date 
          from @test t2
          where t1.id_number = t2.id_number
            and t2.status_date < t1.status_date
          order by t2.status_date desc
          ),received_date) as prev_date 
    from @test t1
) a
order by id_number, status_date

:@Testテーブルをテーブルの名前に置き換えてください。

于 2010-01-30T00:16:54.297 に答える
0

いくつかのサンプル出力は本当に役立ちますが、ID_Number / Statusの組み合わせごとにその情報が必要であると仮定すると、これは意味の推測です。

select ID_Number, Status, EndDate - StartDate as DaysElapsed
from (
    select ID_Number, Status, min(coalesce(received_date, status_date)) as StartDate, max(coalesce(closed_date, status_date)) as EndDate
    from Table1
    group by ID_Number, Status
) a
于 2010-01-30T00:04:54.100 に答える
0

トリッキーなビットは、前のステータスを判別し、それを現在のステータスと同じ行に配置することです。Keyとの間に相関関係がある場合StatusDate(つまり、Key(x) > Key(y)常に意味する) 、少し単純化されStatusDate(x) >= StatusDate(y)ます。残念ながら、そうではないようです。

PS:私はKeyあなたのテーブルの一意の識別子であると仮定しています。他に示すことは何も言っていません。

SELECT  Key,
        ID_Number, 
        (
        SELECT  TOP 1 Key
        FROM    StatusUpdates prev
        WHERE   (prev.ID_Number = cur.ID_Number)
            AND (   (prev.StatusDate < cur.StatusDate)
                OR  (   prev.StatusDate = cur.StatusDate
                    AND prev.Key < cur.Key
                    )
                )
        ORDER BY StatusDate, Key /*Consider index on (ID_Number, StatusDate, Key)*/
        ) PrevKey
FROM    StatusUpdates cur

これを基礎として使用すると、現在または以前のStatusUpdateから必要な他の情報を簡単に推定できます。例えば

SELECT  c.*,
        p.Status AS PrevStatus,
        p.StatusDate AS PrevStatusDate,
        DATEDIFF(d, c.StatusDate, p.StatusDate) AS DaysElapsed
FROM    (
        SELECT  Key,
                ID_Number, 
                Status,
                SattusDate,
                (
                SELECT  TOP 1 Key
                FROM    StatusUpdates prev
                WHERE   (prev.ID_Number = cur.ID_Number)
                    AND (   (prev.StatusDate < cur.StatusDate)
                        OR  (   prev.StatusDate = cur.StatusDate
                            AND prev.Key < cur.Key
                            )
                        )
                ORDER BY StatusDate, Key
                ) PrevKey
        FROM    StatusUpdates cur
        ) c
        JOIN StatusUpdates p ON
            p.Key = c.PrevKey
于 2010-01-30T08:17:26.707 に答える