1

私は本当にこの問題を解決する方法のアイデアがなく、いくつかの支援が必要です-解決策だけでなく、アプローチする方法のアイデアも歓迎されます。

私は次の表を持っています:

TABLE Data
( 
     RecordID
    ,DateAdd
    ,Status
)

このようなサンプル日付で:

11  2012-10-01 OK
11  2012-10-04 NO
11  2012-11-05 NO
22  2012-10-01 OK
33  2012-11-01 NO
33  2012-11-15 OK

そして、この表には次のサンプルデータが含まれています。

TABLE Periods
(
    PeriodID
   ,PeriodName
   ,DateStart
   ,DateEnd
)

1 Octomer  2012-10-01 2012-10-31
2 November 2012-11-01 2012-11-30

私がする必要があるのは、新しいテーブルにデータを入力することです。

TABLE DataPerPeriods
(
    PeriodID,
    RecordID,
    Status
)

これにより、PeriodIDとRecordIDの可能なすべての組み合わせと、可能な場合は期間の最新のステータスが保存されます。与えられた期間のステータスが利用できない場合は、前の期間のステータス。以前のステータスがまったくない場合は、ステータスがNULLになります。

たとえば、次のデータでは、次のようなものが必要です。

1 11 NO //We have status "OK" and "NO", but "NO" is latest for the period
1 22 OK 
1 33 NULL//Because there are no records for this and previous periods
2 11 NO //We get the previos status as there are no records in this periods
2 22 OK //There are not records for this period, but record for last periods is available
2 33 NO //We have status "OK" and "NO", but "OK" is latest for the period

編集:私はすでに最後のテーブルの期間IDとレコードIDを入力しました、私はステータスの更新についてもっと助けが必要です。

4

3 に答える 3

1

最初または最後のステータスを取得する方法を知るために、別の質問に対する私の回答を確認してください。各グループから最初のステータスのみを取得するSQL関数を集約します。

于 2012-11-02T14:23:52.280 に答える
1

これを行うためのより良い方法があるかもしれません。しかし、これはあなたが探しているものを手に入れるために私が知っている最も簡単な道であり、見た目は型破りです。より大きなデータセットの場合、アプローチを変更する必要があるかもしれません。

SELECT p.PeriodID, td.RecordID, statusData.[Status] FROM Periods p
CROSS JOIN (SELECT DISTINCT RecordID FROM Data) td
OUTER APPLY (SELECT TOP 1 [Status], [DateAdd] 
         FROM Data 
         WHERE [DateAdd] <= p.DateEnd 
         AND [RecordID] = td.RecordID 
         ORDER BY [DateAdd] DESC) statusData
ORDER BY p.PeriodID, td.RecordID

CROSS JOINは、RecordIDとDISTINCT期間のすべての可能な組み合わせを提供するものです。

OUTER APPLYは、各期間の終了前に最新のステータスを選択します。

于 2012-11-02T14:35:55.520 に答える
1

OK、ここにアイデアがあります。私を含め、誰もカーソルが好きではありませんが、このような場合に便利なことがあります。

このカーソルは各データレコードをループし、IDを識別子として引き出します。ループ内で単一のデータレコードを検索し、基準を満たす結合のカウントを取得します。

@count = 0の場合、条件は満たされていないため、その期間のレコードを挿入しないでください。

@ Count = 1の場合、条件が満たされているため、その期間のレコードを挿入します。

これらの条件を頻繁に更新する必要がある場合は、ジョブへのクエリを実行して、1分または1時間ごとに実行できます。

お役に立てれば。

DECLARE @ID int
DECLARE merge_cursor CURSOR FAST_FORWARD FOR 
select recordID
from data 
OPEN merge_cursor
FETCH NEXT FROM merge_cursor INTO @ID

WHILE @@FETCH_STATUS = 0
BEGIN

--get join if record is found in the periods
    declare @Count int
    select @Count= count(*) 
    from data a inner join periods b 
    on a.[dateadd] between b.datestart and b.dateend  
    where a.recordID = @ID 

    if @count>0

        --insert into DataPerPeriods(PeriodID, RecordID, Status)
        select b.periodid, a.recordid, a.status 
        from data a inner join periods b on a.[dateadd] between b.datestart and b.dateend --between beginning of  month and end of  month
        where a.recordid = @ID  
    else
        --insert into DataPerPeriods(PeriodID, RecordID, Status)
        select b.periodid, a.recordid, a.status 
        from data a inner join periods b on a.[dateadd] < b.dateend 
        where a.recordID = @ID --fix this area

FETCH NEXT FROM merge_cursor INTO @ID
END

CLOSE merge_cursor 
DEALLOCATE merge_cursor 
于 2012-11-02T14:51:01.787 に答える