2016-07-12 3 views
1

データセットを他のいくつかのデータセットに分割する際に問題が発生しました。これのベースライン:鍵は異なる国で同時に使用できます(国IDは列です)。 1つのキー(列b in picture)は、一定時間後、この場合は120日後に再利用できます。 1つのキーには日付と共に約10のイベントがあります。データをウィンドウに分割してtsqlのウィンドウから最小値を取得する

Picture with sample data (I have colored the theoretical boundaries for each of the periods or whatever you call them)

私がやってみました事、オーバーセット全体やパーティションの最初の日付B列を取り、の分の日付の間の日数を取得するためにdatediff()を使用して全体のセットとそれぞれ別々のイベント。その後、それらをグループ化するためにdatediff/120によって返された番号を使用します。私が本当にやりたかったことは、各セット(セット全体ではなく)の最小日付をとり、それに基づいて計算することです。親切な援助者が私が何をしているのかを理解するのに十分なほど明確に説明してくれることを本当に望みます。今私は考えています...私は、一組の最小日付を得てそれを120で割ったとしても、私は間違った結果を得ることを一種心配しています。どんな提案も感謝しています! DATEDIFF(d,min(dates) OVER (PARTITION BY a, b), dates)/120

Visual explanation of what I need to achieve and how.

   sample data         desired outcome 
| CountryId | Key  |  date  | | CountryId |  Key |  date  | 
|-------------|-------------|--------------| |-------------|-------------|--------------| 
| 2   | 093123124 | 2015-04-16 | | 2   | 093123124 | 2015-04-16 | 
| 2   | 093123124 | 2015-04-16 | | 2   | 093123124 | 2015-11-24 | 
| 2   | 093123124 | 2015-04-17 | | 2   | 093123124 | 2016-04-17 | 
| 2   | 093123124 | 2015-04-17 | 
| 2   | 093123124 | 2015-11-24 | 
| 2   | 093123124 | 2015-11-24 | 
| 2   | 093123124 | 2015-11-25 | 
| 2   | 093123124 | 2015-11-25 | 
| 2   | 093123124 | 2015-11-25 | 
| 2   | 093123124 | 2016-04-17 | 
| 2   | 093123124 | 2016-04-18 | 
| 2   | 093123124 | 2016-04-20 | 
| 2   | 093123124 | 2016-04-21 | 
| 2   | 093123124 | 2016-04-22 | 
+2

あなたがデータをテキストとして投稿した場合、私たちは画像からコピーを貼り付けることができません。私たちにdbスキーマ、サンプルデータ、および期待される出力を示してください。 [** How-to-Ask **](http://stackoverflow.com/help/how-to-ask) \t \t [** START **](http ://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/)質問品質を向上させ、より良い回答を得る方法を学ぼう。 –

+0

データをテキストとして追加したので、コピーしやすく、期待される結果も得られます。ヒントをありがとう。 –

+0

最初は 'DISTINCT'のように見えます...しかし、私はあなたの欲望の出力のための論理を理解しません。 '11-25'はどこに行くの? 'a、b、c 'を使う代わりに、意味のある変数名を使う –

答えて

0

はこのCTEのためのケースのように思える:

私はこのようなものを使用します。次のコードは、各セットが再帰的に各再帰に120日を追加するのを見つけます。

SET DATEFORMAT YMD 
DECLARE @SampleData TABLE( A INT, 
          B NVARCHAR(25), 
          C DATETIME) 


INSERT INTO @SampleData(A, B, C) 
VALUES (2,'093123124', CONVERT(DATETIME, '2015-04-16')), 
     (2,'093123124', CONVERT(DATETIME, '2015-04-16')), 
     (2,'093123124', CONVERT(DATETIME, '2015-04-17')), 
     (2,'093123124', CONVERT(DATETIME, '2015-04-17')), 
     (2,'093123124', CONVERT(DATETIME, '2015-11-24')), 
     (2,'093123124', CONVERT(DATETIME, '2015-11-24')), 
     (2,'093123124', CONVERT(DATETIME, '2015-11-25')), 
     (2,'093123124', CONVERT(DATETIME, '2015-11-25')), 
     (2,'093123124', CONVERT(DATETIME, '2015-11-25')), 
     (2,'093123124', CONVERT(DATETIME, '2016-04-17')), 
     (2,'093123124', CONVERT(DATETIME, '2016-04-18')), 
     (2,'093123124', CONVERT(DATETIME, '2016-04-20')), 
     (2,'093123124', CONVERT(DATETIME, '2016-04-21')), 
     -- (2,'093123124', CONVERT(DATETIME, '2016-03-24')), 
     (2,'093123124', CONVERT(DATETIME, '2016-04-22')); 

WITH lvl1 
AS 
(
    SELECT A, 
      B, 
      C = MIN(C) 
    FROM @SampleData 
    GROUP BY A, 
       B 
), 
lvlOthers 
AS 
(
    SELECT A, 
      B, 
      C 
    FROM lvl1 
    UNION ALL 
    SELECT S.A, 
      S.B, 
      C = MIN(S.C) OVER(PARTITION BY S.A, S.B) 
    FROM lvlOthers 
    INNER JOIN @SampleData AS S ON lvlOthers.A = S.A 
           AND lvlOthers.B = S.B 
           AND S.C > DATEADD(DAY, 120, lvlOthers.C) 
) 

SELECT DISTINCT A, B, C 
FROM lvlOthers 
OPTION (MAXRECURSION 100) 

このコードはパフォーマンスのために微調整されていません。実際、大規模なデータセットではうまく機能しません。

また、最大範囲は、日付の範囲が〜32年を超える場合に増やす必要があります。

+0

驚くばかり!これは正しい軌道に乗るために必要なものです。 –

関連する問題