時間のみを保存するために使用する列varchar
がありますmytime
ここで、5 時間以内に挿入されたすべてのレコードを見つけたいと考えています。
例えば
Select *
from mytable
where **mytime + interval '5' hour > current_Time**
時間のみを保存するために使用する列varchar
がありますmytime
ここで、5 時間以内に挿入されたすべてのレコードを見つけたいと考えています。
例えば
Select *
from mytable
where **mytime + interval '5' hour > current_Time**
誰かが列に詰め込ん'floob'
だり'32:45'
、列に入れたりすると、datetime への暗黙的な変換が失敗する可能性があるため、それは間違ったデータ型であるため、そのケースを処理し、そこに忍び込んだ不良データを処理する必要があります。また、時刻の値を同じ日付に正規化する必要があります。日付のない時刻には日付コンポーネントがありますが、1900-01-01
時間の加算/減算を含むものGETDATE()
は今日の日付の日付コンポーネントになるためです。したがって、そのすべてを処理するには、次のようなものが必要になります(これは、時間が単純に保存され、/が含まれ12:32
ていない12:32.000
か含まれていることを前提としています):AM
PM
-- 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;
この場合、実際には、テーブル全体をスキャンするのではなく、インデックスをシークする可能性があります。