2013-01-21 1 views
9

開始時刻と終了時刻のデータがある場合は、時間、分、秒、平均の長さで合計の長さを計算する必要があります。HAT:MM:SS形式のDATEDIFF

たとえば、結果は45:15:10(45時間15分10秒を意味します)、または30:07(30分07秒)です。

SQL Server 2008 R2を使用しており、時刻が24:59:59を超えると変換に失敗しました。どのように私はこれを行うことができるの任意のアイデア?詳細について

、表の列は、私は月のレコーディング回数、これらのレコードの合計の長さ、および平均の長さを含む月次レポートを作成する必要があるなどIdStartDateTimeEndDateTime、です。私はこのすべてを実行する簡単な方法があるかどうかを知りたいと思います。

+2

すべてを秒に変換して合計し、読み取り可能な形式に手動で変換します。 – Kermit

答えて

5

あなたはtimeに変換すべきではない - 単一の24時間時計の時間でポイントを保存するためのものです、ない期間または間隔が(明確に< 24時間、に独自に制約されていても1データはありません)。代わりに、必要最小限の時間間隔(あなたの場合は秒)でdatediffを実行し、必要な出力形式で数式と文字列の操作を行います(秒をアプリケーションに戻すことが望ましい場合もあります)。報告ツールを使用して、この作業をしてください)。

DECLARE @d TABLE 
(
    id INT IDENTITY(1,1), 
    StartDateTime DATETIME, 
    EndDateTime DATETIME 
); 

INSERT @d(StartDateTime, EndDateTime) VALUES 
(DATEADD(DAY, -2, GETDATE()), DATEADD(MINUTE, 15, GETDATE())), 
(GETDATE()     , DATEADD(MINUTE, 22, GETDATE())), 
(DATEADD(DAY, -1, GETDATE()), DATEADD(MINUTE, 5, GETDATE())), 
(DATEADD(DAY, -4, GETDATE()), DATEADD(SECOND, 14, GETDATE())); 

;WITH x AS (SELECT id, StartDateTime, EndDateTime, 
    d = DATEDIFF(SECOND, StartDateTime, EndDateTime), 
    a = AVG(DATEDIFF(SECOND, StartDateTime, EndDateTime)) OVER() 
    FROM @d 
) 
SELECT id, StartDateTime, EndDateTime, 
    [delta_HH:MM:SS] = CONVERT(VARCHAR(5), d/60/60) 
    + ':' + RIGHT('0' + CONVERT(VARCHAR(2), d/60%60), 2) 
    + ':' + RIGHT('0' + CONVERT(VARCHAR(2), d % 60), 2), 
    [avg_HH:MM:SS] = CONVERT(VARCHAR(5), a/60/60) 
    + ':' + RIGHT('0' + CONVERT(VARCHAR(2), a/60%60), 2) 
    + ':' + RIGHT('0' + CONVERT(VARCHAR(2), a % 60), 2) 
FROM x; 

結果:デルタ< 1時間SS:

id StartDateTime  EndDateTime   delta_HH:MM:SS avg_HH:MM:SS 
-- ------------------- ------------------- -------------- ------------ 
1 2013-01-19 14:24:46 2013-01-21 14:39:46 48:15:00  42:10:33 
2 2013-01-21 14:24:46 2013-01-21 14:46:46 0:22:00  42:10:33 
3 2013-01-20 14:24:46 2013-01-21 14:29:46 24:05:00  42:10:33 
4 2013-01-17 14:24:46 2013-01-21 14:25:00 96:00:14  42:10:33 

これはそれだけでMMは表示されませんよう、あなたが、のために尋ね正確ではありません。このクエリは0:22:00から22:00に上記の結果では2行目にあるデルタ列を変更

;WITH x AS (SELECT id, StartDateTime, EndDateTime, 
    d = DATEDIFF(SECOND, StartDateTime, EndDateTime), 
    a = AVG(DATEDIFF(SECOND, StartDateTime, EndDateTime)) OVER() 
    FROM @d 
) 
SELECT id, StartDateTime, EndDateTime, 
    [delta_HH:MM:SS] = CASE WHEN d >= 3600 THEN 
    CONVERT(VARCHAR(5), d/60/60) + ':' ELSE '' END 
    + RIGHT('0' + CONVERT(VARCHAR(2), d/60%60), 2) 
    + ':' + RIGHT('0' + CONVERT(VARCHAR(2), d % 60), 2), 
    [avg_HH:MM:SS] = CASE WHEN a >= 3600 THEN 
    CONVERT(VARCHAR(5), a/60/60) + ':' ELSE '' END 
    + RIGHT('0' + CONVERT(VARCHAR(2), a/60%60), 2) 
    + ':' + RIGHT('0' + CONVERT(VARCHAR(2), a % 60), 2) 
FROM x; 

:あなたは、簡単なCASE表現とすることを調整することができます。

1

平均化を実行する場合、最善の方法は秒または分数に変換することです。での時間を取得するために

select cast(avg(cast(endtime - starttime as float) as datetime) 
from t 

算術:

select avg(cast(endtime - starttime) as float) 
from t 

あなたが逆のキャストを使用してdatetimeに戻ってそれを変換することができます:あなたのようなことを行うことができますので、一日分画は、SQL Serverで便利ですあなたが望むフォーマット。 。 。それは痛みです。あなたは、最終的な形式の日を含めて、使用して検討するかもしれない:

select cast(floor(cast(<val> as float)*24) as varchar(255))+right(convert(varchar(255), <val>, 120), 6) 

それはあるべき、分、秒convert使用しています。

select right(convert(varchar(255), <val>, 120), 10) 

が24を超える時間を取得するには、ここでは別のアプローチであります左に0で埋められます。その後、時間を別の値として追加します。

4
SELECT CONVERT(time, 
       DATEADD(mcs, 
         DATEDIFF(mcs, 
           '2007-05-07 09:53:00.0273335', 
           '2007-05-07 09:53:01.0376635'), 
         CAST('1900-01-01 00:00:00.0000000' as datetime2) 
        ) 
      ) 
0

違いが大きすぎるとエラーで終了する可能性があるため、Avinashの回答を少し修正しました。HH:mm:ssだけが必要な場合は、次のように秒レベルで区別すれば十分です。

SELECT CONVERT(time, 
    DATEADD(s, 
    DATEDIFF(s, 
     '2018-01-07 09:53:00', 
     '2018-01-07 11:53:01'), 
    CAST('1900-01-01 00:00:00.0000000' as datetime2) 
    ) 
)