2013-01-21 2 views
9

시작 시간과 종료 시간이있는 데이터가있는 경우 시간, 분, 초 및 평균 길이로 총 길이를 계산해야합니다.HAT : MM : SS 형식의 DATEDIFF

예를 들어 결과는 45:15:10 즉 45 시간 15 분 10 초를 의미하거나 30:07은 30 분 07 초를 의미합니다.

우리는 SQL Server 2008 R2을 사용 중이며 시간이 24:59:59 이상이면 변환에 실패했습니다. 내가 어떻게이 일을 할 수 있겠 어?

는 내용은 테이블의 열 내가 녹음이 달의 계산이 포함 된 월별 보고서, 이러한 기록의 총 길이, 평균 길이를 만들 필요가 등, Id, StartDateTime, EndDateTime 있습니다. 나는이 모든 것을 수행하는 쉬운 방법이 있는지 알고 싶습니다.

+2

는 초 모든 변환을 요약 한 후 수동으로 읽을 수있는 형식으로 변환합니다. – Kermit

답변

5

time으로 변환하면 안됩니다. 지속 시간이나 간격이 아닌 하나의 24 시간 시계에 특정 시점을 저장해야합니다 (자체적으로는 <24 시간으로 제한되는 경우도 있습니다. 데이터가 아닙니다). 대신 필요한 최소 간격으로 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; 

결과 :

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 표시되지 않습니다 당신이를 위해 무엇을 요구 : 델타 < 1 시간 동안 SS를. 당신은 간단한 CASE 표현과 그것을 조정할 수 있습니다

;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; 

이 쿼리는 0:22:00에서 22:00에 위의 결과에서 2 행의 델타 열을 변경합니다.

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의 답변을 약간 수정했습니다.mm : 만 HH해야하는 경우 SS를이 같은 초 수준 ONY에서 구별하기에 충분하다 :

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) 
    ) 
)