Cálculo del intervalo de tiempo con t-sql

Dadas dos fechas / horas:

@start_date = '2009-04-15 10:24:00.000' @end_date = '2009-04-16 19:43:01.000' 

¿Es posible calcular el tiempo transcurrido entre las dos fechas en el siguiente formato?

1d 9h 19m

Puede obtener la diferencia entre las dos fechas con la resolución que desee (en su ejemplo, minutos):

 DATEDIFF(minute, @start_date, @end_date) 

A partir de ahí, es una simple cuestión de dividir minutos en horas y horas en días y modificar el rest.

Sé que este hilo es más antiguo y es probable que los participantes originales ya no estén mirando, pero me di con él y ya había escrito un código bastante recientemente para hacer algo muy parecido a lo que jdiaz está solicitando. El resultado se representa como una cadena en formato D: H: M: S.

El primer paso sería obtener el lapso de tiempo en segundos:

 DECLARE @ElapsedS INT SET @ElapsedS = DATEDIFF(second, @start_date, @end_date) 

Ahora crea la siguiente función escalar:

 CREATE FUNCTION [dbo].[udfTimeSpanFromSeconds] ( @Seconds int ) RETURNS varchar(15) AS BEGIN DECLARE --Variable to hold our result @DHMS varchar(15) --Integers for doing the math , @Days int --Integer days , @Hours int --Integer hours , @Minutes int --Integer minutes --Strings for providing the display , @sDays varchar(5) --String days , @sHours varchar(2) --String hours , @sMinutes varchar(2) --String minutes , @sSeconds varchar(2) --String seconds --Get the values using modulos where appropriate SET @Hours = @Seconds/3600 SET @Minutes = (@Seconds % 3600) /60 SET @Seconds = (@Seconds % 3600) % 60 --If we have 24 or more hours, split the @Hours value into days and hours IF @Hours > 23 BEGIN SET @Days = @Hours/24 SET @Hours = (@Hours % 24) END ELSE BEGIN SET @Days = 0 END --Now render the whole thing as string values for display SET @sDays = convert(varchar, @Days) SET @sHours = RIGHT('0' + convert(varchar, @Hours), 2) SET @sMinutes = RIGHT('0' + convert(varchar, @Minutes), 2) SET @sSeconds = RIGHT('0' + convert(varchar, @Seconds), 2) --Concatenate, concatenate, concatenate SET @DHMS = @sDays + ':' + @sHours + ':' + @sMinutes + ':' + @sSeconds RETURN @DHMS END 

Ahora introduce tu tiempo en la función recién creada:

 SELECT TimeSpan = dbo.udfTimeSpanFromSeconds(@ElapsedS) 

Debe producir ‘1: 09: 19: 01’

 CONVERT(varchar,(@end_date-@start_date),108) 

Esto te lo dará como HH: MM: SS

Aclamaciones

DATEDIFF puede devolver valores poco intuitivos. Por ejemplo, las dos fechas siguientes difieren en un segundo, pero DATEDIFF con los parámetros que figuran a continuación e interpretados como otros lo han interpretado anteriormente, devuelve 1 año:

SELECCIONAR DATEDIFF (año, ‘2005-12-31 23:59:59’, ‘2006-01-01 00:00:00’)

Mire la documentación de MSDN para DATEDIFF para entender cómo funciona.

datediff (datepart, date1, date2);

La respuesta de Rex es más completa.

Así es cómo formatea la fechada (50d 8h 35m) en una consulta:

 Declare @Date1 as Datetime, @Date2 as Datetime Set @Date1 = '2005-01-01 08:00:00' Set @Date2 = '2005-02-20 16:35:30' Select CAST(DATEDIFF(Minute,@Date1, @Date2)/60/24 as Varchar(50)) ++ 'd ' ++ CAST((DATEDIFF(Minute,@Date1, @Date2)/60)-((DATEDIFF(Minute,@Date1, @Date2)/60/24)*24) as Varchar(50)) ++ 'h ' ++ CAST((DATEDIFF(Minute,@Date1, @Date2)) - (DATEDIFF(HOUR,@Date1, @Date2)*60) as Varchar(50)) ++ 'm' as FormattedDateDiff 
 DECLARE @FirstDate DATETIME, @SecondDate DATETIME, @result VARCHAR(MAX) SELECT @FirstDate = '2017-03-01 09:54:00.637', @SecondDate = GETDATE() DECLARE @Day INT,@Month INT,@Hour INT, @Minute INT,@TotalSeconds INT,@Year INT SELECT @TotalSeconds = ABS(DATEDIFF(SECOND,@FirstDate,@SecondDate)) -- Standard values in seconds DECLARE @YearSeconds INT, @MonthSeconds INT, @DaySeconds INT, @HourSeconds INT, @MinuteSeconds INT SELECT @MinuteSeconds = 60 SELECT @HourSeconds = 60 * @MinuteSeconds SELECT @DaySeconds = 24 * @HourSeconds SELECT @MonthSeconds = 30 * @DaySeconds SELECT @YearSeconds = 12 * @MonthSeconds --SELECT @MinuteSeconds AS [Minutes], @HourSeconds AS [Hours], @DaySeconds AS [Day],@MonthSeconds AS [Month],@YearSeconds AS [Year] IF @TotalSeconds < @MinuteSeconds BEGIN SELECT @result = CAST(@TotalSeconds AS NVARCHAR(20)) + ' seconds ago' END ELSE IF @TotalSeconds < @HourSeconds BEGIN SELECT @result = CAST(ABS(DATEDIFF(MINUTE,@FirstDate,@SecondDate)) AS NVARCHAR(20)) + ' minutes ago' END ELSE IF @TotalSeconds < @DaySeconds BEGIN SELECT @result = CAST(ABS(DATEDIFF(HOUR,@FirstDate,@SecondDate)) AS NVARCHAR(20)) + ' hours ago' END ELSE IF @TotalSeconds < @MonthSeconds BEGIN SELECT @result = CAST(ABS(DATEDIFF(DAY,@FirstDate,@SecondDate)) AS NVARCHAR(20)) + ' days ago' END ELSE IF @TotalSeconds < @YearSeconds BEGIN SELECT @result = CAST(ABS(DATEDIFF(MONTH,@FirstDate,@SecondDate)) AS NVARCHAR(20)) + ' months ago' END ELSE IF @TotalSeconds > @YearSeconds BEGIN SELECT @result = CAST(ABS(DATEDIFF(YEAR,@FirstDate,@SecondDate)) AS NVARCHAR(20)) + ' year ago' END SELECT @result