2012-02-02 24 views
1

SQL Serverにさまざまな日付範囲を保持するテーブルがあります。私は日付スタンプが上記の範囲のいずれかに存在しない別のテーブルからレコードを選択する必要が日付が複数の日付範囲のテーブルにないレコードを選択するSQL Server

start_date     end_date 
=======================  ======================= 
2011-02-21 00:00:00.000  2011-02-25 00:00:00.000 
2011-04-18 00:00:00.000  2011-04-29 00:00:00.000 
2011-05-31 00:00:00.000  2011-06-03 00:00:00.000 
2011-07-21 00:00:00.000  2011-08-31 00:00:00.000 
2011-10-24 00:00:00.000  2011-10-28 00:00:00.000 
2011-12-19 00:00:00.000  2012-01-02 00:00:00.000 
2012-02-13 00:00:00.000  2012-02-17 00:00:00.000 
2012-04-02 00:00:00.000  2012-04-13 00:00:00.000 
2012-06-04 00:00:00.000  2012-06-08 00:00:00.000 
2012-07-20 00:00:00.000  2012-08-31 00:00:00.000 
2012-10-29 00:00:00.000  2012-11-02 00:00:00.000 
2012-12-24 00:00:00.000  2013-01-01 00:00:00.000 
2013-02-10 00:00:00.000  2013-02-16 00:00:00.000 
2013-03-24 00:00:00.000  2013-04-06 00:00:00.000 
2013-05-26 00:00:00.000  2013-06-01 00:00:00.000 
2013-07-24 00:00:00.000  2013-08-31 00:00:00.000 
2013-10-27 00:00:00.000  2013-11-02 00:00:00.000 

- :以下のよう

表は、開始日と終了日を持っています。

上記の表の開始日と終了日が同じ場合があります。これは、除外する日が1日だけであることを示しています。

私の最初のアイデアは、上記の範囲のすべての日付を拡張し、次に存在しないSELECTを実行するか、これを達成するより効率的な方法がありますか?

+0

もう1つのテーブルには日付のみが格納されているか、時間が含まれているかどうかは関係ありません。たとえば、除外表'02/02/2012 'を開始日と終了日とし、'02/02/2012 12:00'の値を比較することができます。提出された回答のほとんどで、これは除外されないため、重要な情報のようです。 – GarethD

+0

投稿ごとに、日付は次の形式になります。2012-12-24 00:00:00.000 いつものように見えます00:00:00.000 – JsonStatham

答えて

1

範囲テーブルを使用して左結合を行い、一致句を除外するwhere句を追加できます。

SELECT anothertable.* FROM anothertable 
LEFT JOIN range on anothertable.date >= range.start_date and anothertable.date <= range.end_date 
WHERE range.start_date IS NULL 
3
SELECT t.* 
FROM AnotherTable t 
WHERE NOT EXISTS(
    SELECT 1 
    FROM TblDate d 
    WHERE d.start_date <= t.DateColumn 
    AND d.end_date >= t.DateColumn 
) 

編集:ただ、これはあなたの最初のアイデアだったことがわかります。だから私はそれが最もシンプルで最速のアプローチだと考えています。

http://sqlserverperformance.idera.com/tsql-optimization/finding-nonexistent-records-hurry/

+0

前のコメントについて申し訳ありませんが、あなたは正しいです。私は「タイムスタンプ」として「日付スタンプ」を誤読しました。 –

1

は、以下の(と思う)を使用しての提案と同じ最終結果よりも効率的である。ここでは、このトピックを読んで何かです。私が確信している唯一の事は、開始日が終了日に等しいというあなたの基準を理解してから1日を除いた場合です。

SELECT * 
FROM Table1 
     LEFT JOIN 
     ( SELECT Start_date, CASE WHEN End_Date = Start_Date THEN DATEADD(MILLISECOND, -1, DATEADD(DAY, 1, End_Date)) ELSE End_Date END [End_Date] 
      FROM table2 
     ) Exc 
      ON table.DateColumn BETWEEN Exc.Start_Date AND Exc.End_Date 
WHERE Exc.Start_Date IS NULL 
1

あなたは、2つの条件をチェックする必要があります。 1日は範囲 2日の間であり、同じstart_dateのような日が、後でEND_DATEより日に(あなたは時間を持っていないました、分、秒の範囲で)

SELECT * FROM VALUE_TABLE 
LEFT JOIN DATE_RANGE_TABLE ON 
    YEAR(VALUE_TABLE.CHECK_DATE) = YEAR(start_date) 
    and MONTH (VALUE_TABLE.CHECK_DATE) = MONTH (start_date) 
    AND DAY (VALUE_TABLE.CHECK_DATE) = DAY (start_date) 
    OR VALUE_TABLE.CHECK_DATE BETWEEN start_date and end_date 
WHERE start_date IS NULL 
+3

@chris - スタックオーバーフローでは、 '[sql-server]'タグがMicrosoft SQL Serverに特別に適用されると想定できます。あなたは短い要約のためにタグの上にマウスを置くことができます。 –

関連する問題