2

私は下の表を持っています

2012-05-24 19:00:00.000
2012-07-27 15:51:18.750
2012-07-30 09:40:25.333
2012-07-30 14:25:27.563
2012-07-27 15:51:18.750
2012-07-30 09:40:25.333
2012-07-30 14:25:27.563
2012-05-12 09:23:16.850
2012-05-12 18:00:00.000

範囲選択をしようとしているので、たとえば

SELECT * FROM RUN WHERE RUN_DATETIME = '14:25:29.563' 

これは非常に単純な選択ですが、私の問題は、コードを検索している日付が上の表の内容から 30 秒もずれていることです。そのため、上記と同じことを 30 秒のウィンドウで実行できるようにする必要があります。これを行う最善の方法が何であるかはわかりません。

この選択は別の行に基づくものではなく、ウィンドウ内の行 RUN_DATE のみに基づいています。

SQL Server 2008 R2 を使用しています

4

4 に答える 4

3
SELECT * FROM RUN
WHERE RUN_DATETIME < DATEDADD(s, '14:25:29.563', 30) AND
      RUN_DATETIME > DATEDADD(s, '14:25:29.563', -30)

podiluska の回答よりも複雑に見えますが、これは範囲を事前に計算することでインデックスで機能します。

于 2012-08-03T09:28:33.743 に答える
1
SELECT * 
FROM RUN 
WHERE ABS(DATEDIFF(s, RUN_DATETIME , '14:25:29.563' ))< 30
于 2012-08-03T09:25:09.557 に答える
1
SELECT
  *
FROM
  RUN
WHERE
      RUN_DATETIME >= DATEADD(second, -30, '14:25:29.563')
  AND RUN_DATETIME <  DATEADD(second,  30, '14:25:29.563')

これはABS(DATEDIFF())バージョンよりも長いです。ただし、インデックス付きフィールドに適用すると、はるかに高速になります。

これは、1 つの順次ブロック内にすべてのレコードが必要であることをオプティマイザーが簡単に確認できるためです。最初を検索してから最後を検索し、その間のすべてを返すことができます。

このABS(DATEDIFF())バリエーションでは、すべての行を個別にチェックする必要があり、インデックスや範囲シークは使用しません。テーブル全体のフルスキャンです。


編集:

>=と を使用していることにも注意してください<。これは、時間範囲の標準的な方法です。

たとえばval >= 0 AND val < 60val >= 60 AND val < 120の値val = 60が 1 つの時間範囲でのみカウントされるようにします。

于 2012-08-03T09:28:36.457 に答える
0

RUN_DateTime 列には日付が含まれていると思いますが、ここで行っている比較は「14:25:29.563」の時間のみです。私はpodiluskaの答えに同意します。RUN_DateTime 列から日、月、年を取り出して、「14:25:29.563」を日付に変換するだけです。Date_Part 関数でそれを行うことができます。

于 2012-08-03T09:52:38.887 に答える