2012-12-13 4 views
10

J'ai une table SQL Server qui a une colonne "Time". La table est une table de journal qui contient les messages d'état et les horodatages de chaque message. La table de journal est insérée via un fichier batch. Une colonne d'ID regroupe les lignes. Chaque fois que le fichier batch s'exécute, il initialise l'ID et écrit les enregistrements. Ce que je dois faire est obtenir le temps écoulé du premier enregistrement dans un ensemble d'identification au dernier enregistrement du même ensemble d'identification. J'ai commencé à jouer avec sélectionner Max (Time) - Min (Time) de logTable où id = mais je n'arrivais pas à trouver comment le formater correctement. J'en ai besoin en HH: MM: SS.SQL Server - calculer le temps écoulé entre deux horodatages au format HH: MM: SS

+0

S'il vous plaît laissez-nous savoir le type de données de la colonne « Time ». DateTime, DateTime2, Heure, Horodatage, etc. –

+0

@Time ... mon mauvais, DateTime – MikeTWebb

Répondre

8

Votre meilleur pari est de calculer la différence en secondes, et d'utiliser une fonction pour formater le résultat. La fonction native CONVERT() peut sembler fonctionner correctement tant que votre intervalle est inférieur à 24 heures. Mais CONVERT() n'est pas une bonne solution pour cela.

create table test (
    id integer not null, 
    ts datetime not null 
); 

insert into test values (1, '2012-01-01 08:00'); 
insert into test values (1, '2012-01-01 09:00'); 
insert into test values (1, '2012-01-01 08:30'); 
insert into test values (2, '2012-01-01 08:30'); 
insert into test values (2, '2012-01-01 10:30'); 
insert into test values (2, '2012-01-01 09:00'); 
insert into test values (3, '2012-01-01 09:00'); 
insert into test values (3, '2012-01-02 12:00'); 

Les valeurs ont été choisies de telle sorte que pour

  • id = 1, le temps écoulé est de 1 heure
  • id = 2, le temps écoulé est de 2 heures, et
  • id = 3, le temps écoulé est de 3 heures.

Cette instruction SELECT comprend une colonne qui calcule secondes, et une qui utilise CONVERT() avec soustraction.

select t.id, 
     min(ts) start_time, 
     max(ts) end_time, 
     datediff(second, min(ts),max(ts)) elapsed_sec, 
     convert(varchar, max(ts) - min(ts), 108) do_not_use 
from test t 
group by t.id; 

ID START_TIME     END_TIME     ELAPSED_SEC DO_NOT_USE 
1 January, 01 2012 08:00:00 January, 01 2012 09:00:00 3600   01:00:00 
2 January, 01 2012 08:30:00 January, 01 2012 10:30:00 7200   02:00:00 
3 January, 01 2012 09:00:00 January, 02 2012 12:00:00 97200  03:00:00 

Notez la confusion "03:00:00" pour la différence de 27 heures sur numéro d'identification 3.

Function to format elapsed time in SQL Server

+0

@Catcall .... question: votre requête a fonctionné pour ces deux dates qui ont duré plus de deux jours (2012-12-13 15: 10: 12.050 et 2012-12-12 20: 16: 47.160). Votre résultat était de 68005 secondes et 18:53:24. Cela semble juste. Je ne sais pas pourquoi do_not_use 18:53:24 est là? – MikeTWebb

+1

CONVERT() renvoie la mauvaise réponse pour les intervalles de plus de 24 heures. La différence entre vos deux horodatages est inférieure à 24 heures. La colonne "do_not_use" est destinée à vous décourager d'utiliser CONVERT() pour formater les intervalles. –

+0

@Catcall ... oui, j'ai compris la signification de la colonne "do_not_use". J'étais curieux de savoir CONVERT() .... et votre explication est parfaite. Merci! – MikeTWebb

0

select convert(varchar, Max(Time) - Min(Time) , 108) from logTable where id=...

+0

Va afficher "03:00:00" pour une différence de 27 heures entre les deux horodatages ... – XpiritO

8

mise à jour:

calculer correctement une plage temporelle dans SQL Server, même si plus de 24 heures:

-- Setup test data 
declare @minDate datetime = '2012-12-12 20:16:47.160' 
declare @maxDate datetime = '2012-12-13 15:10:12.050' 

-- Get timespan in hh:mi:ss 
select cast(
     (cast(cast(@maxDate as float) - cast(@minDate as float) as int) * 24) /* hours over 24 */ 
     + datepart(hh, @maxDate - @minDate) /* hours */ 
     as varchar(10)) 
    + ':' + right('0' + cast(datepart(mi, @maxDate - @minDate) as varchar(2)), 2) /* minutes */ 
    + ':' + right('0' + cast(datepart(ss, @maxDate - @minDate) as varchar(2)), 2) /* seconds */ 

-- Returns 18:53:24 

cas Edge qui montrent l'inexactitude sont particulièrement les bienvenus! SQL Server ne prend pas en charge le type de données d'intervalle standard SQL.

+0

@Tim .... cela fonctionne presque. Pour ces deux dates (2012-12-13 15: 10: 12.050 et 2012-12-12 20: 16: 47.160), votre requête a renvoyé un résultat de 19:54:25 lorsque la valeur réelle est 18:53:24. Des idées? – MikeTWebb

+0

@MikeTWebb vous pourriez trouver la version actuelle de fonctionner correctement si vous ne voulez pas utiliser une fonction ou être limité dans combien d'heures peut être représenté. –

1

Voir si cela aide. Je peux définir des variables pour les jours écoulés, heures, minutes, secondes. Vous pouvez le formater selon vos préférences ou l'inclure dans une fonction définie par l'utilisateur.

Remarque: N'utilisez pas DateDiff (hh, @ Date1, @ Date2). Ce n'est pas fiable! Il arrondit de façon imprévisible

Compte tenu de deux dates ... (Dates exemples: deux jours, trois heures, 10 minutes, 30 secondes différence)

declare @Date1 datetime = '2013-03-08 08:00:00' 
declare @Date2 datetime = '2013-03-10 11:10:30' 
declare @Days decimal 
declare @Hours decimal 
declare @Minutes decimal 
declare @Seconds decimal 

select @Days = DATEDIFF(ss,@Date1,@Date2)/60/60/24 --Days 
declare @RemainderDate as datetime = @Date2 - @Days 
select @Hours = datediff(ss, @Date1, @RemainderDate)/60/60 --Hours 
set @RemainderDate = @RemainderDate - (@Hours/24.0) 
select @Minutes = datediff(ss, @Date1, @RemainderDate)/60 --Minutes 
set @RemainderDate = @RemainderDate - (@Minutes/24.0/60) 
select @Seconds = DATEDIFF(SS, @Date1, @RemainderDate)  
select @Days as ElapsedDays, @Hours as ElapsedHours, @Minutes as ElapsedMinutes, @Seconds as ElapsedSeconds 
0

Espérons que cela vous aide à obtenir l'heure exacte entre deux horodateurs

Create PROC TimeDurationbetween2times(@iTime as time,@oTime as time) 
As 
Begin 

DECLARE @Dh int, @Dm int, @Ds int ,@Im int, @Om int, @Is int,@Os int  

SET @Im=DATEPART(MI,@iTime) 
SET @Om=DATEPART(MI,@oTime) 
SET @Is=DATEPART(SS,@iTime) 
SET @Os=DATEPART(SS,@oTime) 

SET @Dh=DATEDIFF(hh,@iTime,@oTime) 
SET @Dm = DATEDIFF(mi,@iTime,@oTime) 
SET @Ds = DATEDIFF(ss,@iTime,@oTime) 

DECLARE @HH as int, @MI as int, @SS as int 

if(@Im>@Om) 
begin 
SET @[email protected] 
end 
if(@Is>@Os) 
begin 
SET @[email protected] 
end 

SET @HH = @Dh 
SET @MI = @Dm-(60*@HH) 
SET @SS = @Ds-(60*@Dm) 

DECLARE @hrsWkd as varchar(8)   

SET @hrsWkd = cast(@HH as char(2))+':'+cast(@MI as char(2))+':'+cast(@SS as char(2))   

select @hrsWkd as TimeDuration 

End 
2
DECLARE @EndTime AS DATETIME, @StartTime AS DATETIME 

SELECT @StartTime = '2013-03-08 08:00:00', @EndTime = '2013-03-08 08:30:00' 

SELECT CAST(@EndTime - @StartTime AS TIME) 

Résultat: 00:30:00.0000000

Le format de résultat correspond à vos attentes.

+0

Cela ne fonctionne que dans SQL Server 2008+, mais c'est une excellente solution en supposant que vous pouvez garantir la version. –

+0

Échec si le temps est supérieur à 24 heures – Dave

1

La meilleure et simple:

Convert(varchar, {EndTime} - {StartTime}, 108) 

Tout comme Anri noté.

1

Utilisez le DATEDIFF pour retourner la valeur en millisecondes, secondes, minutes, heures, ...

DATEDIFF (intervalle, date1, date2)

intervalle REQUIS - Le temps/date partie revenir. Peut-être l'une des valeurs suivantes:

year, yyyy, yy = Year 
quarter, qq, q = Quarter 
month, mm, m = month 
dayofyear = Day of the year 
day, dy, y = Day 
week, ww, wk = Week 
weekday, dw, w = Weekday 
hour, hh = hour 
minute, mi, n = Minute 
second, ss, s = Second 
millisecond, ms = Millisecond 

date1, date2REQUISE - Les deux dates pour calculer la différence entre

Questions connexes