0

時間のみを保存するために使用する列varcharがありますmytime

ここで、5 時間以内に挿入されたすべてのレコードを見つけたいと考えています。

例えば

Select *
from mytable
where **mytime + interval '5' hour > current_Time**
4

1 に答える 1

4

誰かが列に詰め込ん'floob'だり'32:45'、列に入れたりすると、datetime への暗黙的な変換が失敗する可能性があるため、それは間違ったデータ型であるため、そのケースを処理し、そこに忍び込んだ不良データを処理する必要があります。また、時刻の値を同じ日付に正規化する必要があります。日付のない時刻には日付コンポーネントがありますが、1900-01-01時間の加算/減算を含むものGETDATE()は今日の日付の日付コンポーネントになるためです。したがって、そのすべてを処理するには、次のようなものが必要になります(これは、時間が単純に保存され、/が含まれ12:32ていない12:32.000か含まれていることを前提としています):AMPM

-- first, get a variable to hold 5 hours ago on 1900-01-01:

DECLARE @cutoff DATETIME;
SET @cutoff = DATEADD(DAY,-DATEDIFF(DAY,0,GETDATE()),DATEADD(HOUR,-5,GETDATE()));

-- now use that in the WHERE clause
-- and also check that the value can be converted
-- to a date and it is in hh:mm format.

-- need CASE expression here because you can't
-- control the order in which WHERE clauses are
-- evaluated by SQL Server.

SELECT ... WHERE
CASE 
  WHEN ISDATE(MyTime) = 1 
  AND MyTime LIKE '[ 0-2][0-6]:[0-6][0-9]'
THEN CONVERT(DATETIME, MyTime) END > @cutoff;

SQL Server 2008 以降では、データ型を使用できるためTIME、日付の合体について心配する必要はありません。また、SQL Server 2012 以降では、 を使用TRY_CONVERTして、面倒なCASEロジックをすべて回避できます。

本当の答え:列を修正し、適切なデータ型を使用してください。時間データを文字列列に格納する理由はまったくありません。次に、次のように言うことができます。

WHERE MyTime > @cutoff;

この場合、実際には、テーブル全体をスキャンするのではなく、インデックスをシークする可能性があります。

于 2013-08-13T20:16:00.933 に答える