web-dev-qa-db-fra.com

SQL Server - calcule le temps écoulé entre deux horodatages au format HH: MM: SS

J'ai une table SQL Server qui a une colonne "Time". La table est une table de journal contenant les messages d'état et les horodatages des maisons. La table de journal est insérée dans un fichier de commandes. Il y a une colonne ID qui regroupe les lignes. Chaque fois que le fichier de commandes est exécuté, il initialise l'ID et écrit les enregistrements. Ce que je dois faire, c'est obtenir le temps écoulé depuis le premier enregistrement d'un jeu d'ID jusqu'au dernier enregistrement du même jeu d'ID. J'ai commencé à jouer avec sélectionnez Max (Time) - Min (Time) à partir de logTable où id = mais je ne savais pas comment le formater correctement. J'en ai besoin en HH: MM: SS.

11
MikeTWebb

SQL Server ne prend pas en charge le type de données d'intervalle standard SQL. Votre meilleur choix 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 manière à ce que 

  • 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 inclut une colonne qui calcule les secondes et une autre 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 le "03:00:00" trompeur pour la différence de 27 heures sur le numéro d'identification 3.

Fonction permettant de formater le temps écoulé dans SQL Server

MIS À JOUR:

Calculer correctement une période 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

Les cas délicats qui montrent des inexactitudes sont particulièrement bienvenus!

11
Tim Lehner
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

Formatez le résultat comme bon vous semble.

3
Jeff

Utilisez DATEDIFF pour renvoyer une valeur en millisecondes, secondes, minutes, heures, ...

DATEDIFF (intervalle, date1, date2)

intervalle REQUIS - La partie heure/date à renvoyer. 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, date2 REQUIS - Les deux dates pour calculer la différence entre

1
AquaAlex

Voir si cela aide. Je peux définir des variables pour les jours, les heures, les minutes, les secondes écoulés . Vous pouvez le formater à votre guise 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 tourne de manière imprévisible

Étant donné deux dates ......... (Exemples de dates: deux jours, trois heures, 10 minutes, 30 secondes de 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
1
Kent Keller

Le meilleur et simple moyen:

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

Tout comme Anri l'a noté.

1
Tim Budworth

J'espère que cela vous aide à obtenir l'heure exacte entre deux horodatages

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 @Dh=@Dh-1  
end  
if(@Is>@Os)  
begin  
SET @Dm=@Dm-1  
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
0
sairam

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

0
Anri