3

2 つの SQL DateTime 値の差を秒単位で抽出しようとしています。パフォーマンス監視のために小数点以下の桁数を使用しています。

「作成」および「終了」日時を持つテーブル「ページログ」があります。過去には、次のことができました。

SELECT DATEDIFF(ms, pagelog_created, pagelog_end)/1000.00 as pl_duration FROM pagelog

ただし、次のエラーが発生し始めました。

Msg 535, Level 16, State 0, Line 1
The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.

このエラーに対して、精度の低い測定単位を使用する必要があるという多くの回答を見てきました。しかし、DATEDIFF(s,..,..) は INT の結果を返し、必要な精度が失われるため、2.1 秒と 2.9 秒を区別する必要がある場合、これはほとんど役に立ちません。

私は当初、これはテーブル内のいくつかの値が巨大な範囲を持っているために発生したと考えていましたが、これを実行しています:

SELECT DATEDIFF(s, pagelog_created, pagelog_end) FROM pagelog
ORDER BY DATEDIFF(s, pagelog_created, pagelog_end) DESC

30837 の最大値を返します。これは 8.5 時間または 30,837,000 ミリ秒であり、私の知る限り SQL INT の範囲内ですか?

2つのオプションがあると言える限り、どんな助けも大歓迎です:

  • 何らかの方法でデータの問題を修正し、犯人の値を見つけます
  • 値の差を計算する別の方法を見つける

ありがとう!

4

4 に答える 4

2

StackOverflowの魔法はうまくいったようですが、先週この問題に何時間も費やしましたが、質問を読み直して、これを解決しました。私はこの問題を抱えている他の人を助けるために答えを更新すると思いました。

ここでの問題は、広い範囲があったことではなく、の範囲があったことです。これは明らかに負のオーバーフローになります。SQL Serverのエラーがもう少し説明的であると便利でしたが、技術的には間違っていません。

したがって、私の場合、これは値を返していました。

SELECT * FROM pagelog
WHERE pagelog_created > pagelog_end

値を削除するか、初期結果セットから値を省略してください。

IvanGとAndriyMにもご回答いただきありがとうございます

于 2013-02-26T10:26:21.207 に答える
1

次のようにオーバーフローを回避しようとすることができます。

DECLARE @dt1 DATETIME = '2013-01-01 00:00:00.000'
DECLARE @dt2 DATETIME = '2013-06-01 23:59:59.997'

SELECT  DATEDIFF(DAY, CAST(@dt1 AS DATE), CAST(@dt2 AS DATE)) * 24 * 60 * 60
SELECT  DATEDIFF(ms, CAST(@dt1 AS TIME), CAST(@dt2 AS TIME))/1000.0

SELECT DATEDIFF(DAY, CAST(@dt1 AS DATE), CAST(@dt2 AS DATE)) * 24 * 60 * 60 
        + DATEDIFF(ms, CAST(@dt1 AS TIME), CAST(@dt2 AS TIME))/1000.0 

DATE最初に、の部分から丸一日の秒数を取得しDATETIME、次にそのTIME部分から秒数を追加します。その後、それらを追加するだけです。

DATEDIFFデータ型の最小時間と最大時間ではTIMEオーバーフローを生成できないため、エラーは発生しません。

于 2013-02-25T10:00:26.293 に答える
0

もちろん、次のようなこともできます。

SELECT
  DATEDIFF(ms, DATEADD(s, x.sec, pagelog_created), pagelog_end) * 0.001
  + x.sec AS pl_duration
FROM pagelog
CROSS APPLY (
  SELECT DATEDIFF(s, pagelog_created, pagelog_end)
) x (sec)
;

ご覧のとおり、最初にとの間の秒の差pagelog_createdpagelog_end取得され、次に秒が加算されpagelog_created、その値との間のミリ秒単位の差pagelog_endが計算されて秒に加算されます。

ただし、調査によると、テーブルにはオーバーフローを引き起こす可能性のある行がないように思われるため、その特定のフラグメントエラーの原因であるかどうかも再確認します。

于 2013-02-25T17:32:59.347 に答える
0
with cte as(
select rownum = row_number() over(partition by T.TR_ID order by T.[date]),
T.* from [dbo].[TR_Events] T 
)
select  cte.[date],nex.[date],convert(varchar(10),datediff(s, cte.[date], nex.[date])/3600)+':'+
convert(varchar(10),datediff(s, cte.[date], nex.[date])%3600/60)+':'+
convert(varchar(10),(datediff(s,cte.[date], nex.[date])%60)) 
from cte
left join cte prev on prev.rownum = cte.rownum - 1
left join cte nex on nex.rownum = cte.rownum + 1
于 2016-10-19T09:13:42.223 に答える