0

SQL Server を介してテーブルに挿入されたばかりの日付キーにこの問題があります。これらは、以下に示す方法で繰り返し入力されます。

  • 20130501
  • 20130502
  • 20130503
  • ...

私は現在、日付の1つがスキップされた行を見つけようとしています。

  • 20130504
  • 20130506
  • 20130507

私はまだ SQL Server の初心者であり、CURSOR を見てきましたが、これをクエリする方法を理解するのに苦労しています。どんな助けでも大歓迎です。ありがとう。

4

2 に答える 2

0

Itzik Ben-Gan の考え方のいくつかのトリックを使用します。ギャップを見つける最も簡単な方法は、集計表を使用することです。テーブル変数に小さなものを作成する方法は次のとおりですが、この種の作業には非常に便利なので、実証済みの Numbers テーブルを作成することをお勧めします。これを行う方法については、ここでたくさんの例を見つけることができます。

最初に数表を作成します

DECLARE @Numbers TABLE ( [Number] INT );

    INSERT  INTO @Numbers
    (
      Number
    )
    SELECT TOP 1000
            ROW_NUMBER() OVER (ORDER BY [s1].[object_id]) AS Number
    FROM    sys.objects s1
    CROSS JOIN sys.objects s2

次に、例を再作成するために一時テーブルを作成する必要がありました

DECLARE @ExampleDates TABLE ( [RecordDateKey] INT );

INSERT  INTO @ExampleDates
    ( [RecordDateKey] )
VALUES  ( 20130501 ),
        ( 20130502 ),
        ( 20130503 ),
        ( 20130504 ),
        ( 20130506 ),
        ( 20130507 ),
        ( 20130508 ),
        ( 20130511 );

この構文は 2008-r2 以降でのみ機能しますが、データをステージングしているだけなので、大したことではありません。この例をテストする他の人のために、このメモを残しておきます。

最後に、変換作業を行う必要があります。

より大きなセットの場合、このデータを実証することは有益かもしれませんが、この小さな例では cte で十分です。

WITH    date_convert
      AS (
           SELECT   [RecordDateKey]
                  , CONVERT(DATETIME, CAST([RecordDateKey] AS VARCHAR(50)), 112) [RecordDate]
           FROM     @ExampleDates ed
         ) ,
    date_range
      AS (
           SELECT   DATEDIFF(DAY, MIN([RecordDate]), MAX([RecordDate])) [Range]
                  , MIN([RecordDate]) [StartDate]
           FROM     [date_convert]
         ) ,
    all_dates
      AS (
           SELECT   CONVERT(INT, CONVERT(VARCHAR(8), DATEADD(DAY, num.[Number], [StartDate]), 112)) AS [RecordDateKey]
                  , DATEADD(DAY, num.[Number], [StartDate]) [RecordDate]
           FROM     @Numbers num
           CROSS JOIN [date_range] dr
           WHERE    num.[Number] <= dr.[Range]
         )
 SELECT [RecordDateKey]
      , [RecordDate]
 FROM   all_dates ad
 WHERE  NOT EXISTS ( SELECT 1
                     FROM   [date_convert] dc
                     WHERE  ad.[RecordDate] = dc.RecordDate )
  • date_convert: 簡単な比較と dateadd のために、指定したキーを datetime に変更します。

  • date_range: 日付の範囲と範囲の開始位置を検索します。

  • all_dates: 範囲内に存在するはずのすべての日付を検索します。

  • 最後の選択では、生成されたセットにないデータ内のレコードが検索されます。

このコードを使用すると、これが私の出力でした。これにより、ギャップのサイズに関係なくギャップが検出されます。これは、現在受け入れられている回答の問題のようです。

RecordDateKey   RecordDate
-------------   ----------
20130505        2013-05-05 00:00:00.000
20130509        2013-05-09 00:00:00.000
20130510        2013-05-10 00:00:00.000
于 2013-05-11T12:41:50.390 に答える
0
SELECT *
FROM table
WHERE date - 1 NOT IN (SELECT date FROM table)

おそらく非常に効率的ではありませんが、うまくいくはずです。

于 2013-05-10T20:43:11.283 に答える