una operaciones obtener meses mes fechas fecha entre ejemplos edad dias con calcular años año sql sql-server sql-server-2005

operaciones - obtener mes y año de una fecha sql



¿Cómo usar DATEDIFF para devolver año, mes y día? (7)

¿Cómo puedo usar DATEDIFF para devolver la diferencia entre dos fechas en años, meses y días en SQL Server 2005?

DATEDIFF (fecha, fecha)

Cómo dar como resultado que: 2 año 3 mes 10 día

¿Alguien puede completar este t-sql?

ALTER FUNCTION [dbo].[gatYMD](@dstart VARCHAR(50), @dend VARCHAR(50)) RETURNS VARCHAR(50) AS BEGIN DECLARE @yy INT DECLARE @mm INT DECLARE @getmm INT DECLARE @dd INT SET @yy = DATEDIFF(yy, @dstart, @dend) SET @mm = DATEDIFF(mm, @dstart, @dend) SET @dd = DATEDIFF(dd, @dstart, @dend) SET @getmm = ABS(DATEDIFF(mm, DATEADD(yy, @yy, @dstart), @dend)) RETURN ( Convert(varchar(10),@yy) + ''year'' + Convert(varchar(10),@mm) + ''month'' + Convert(varchar(10),@dd) + ''day'' ) END


Aquí está mi solución a la función de Eric:

DECLARE @getmm INT DECLARE @getdd INT SET @yy = DATEDIFF(yy, @dstart, @dend) SET @mm = DATEDIFF(mm, @dstart, @dend) SET @dd = DATEDIFF(dd, @dstart, @dend) SET @getmm = ABS(DATEDIFF(mm, DATEADD(yy, @yy, @dstart), @dend)) SET @getdd = ABS(DATEDIFF(dd, DATEADD(mm, DATEDIFF(mm, DATEADD(yy, @yy, @dstart), @dend), DATEADD(yy, @yy, @dstart)), @dend)) RETURN ( Convert(varchar(10),@yy) + ''year'' + Convert(varchar(10),@getmm) + ''month'' + Convert(varchar(10),@getdd) + ''day'' )

Buena llamada sobre el uso de ABS para manejar si la fecha de inicio es posterior a la fecha de finalización.

Esta:

WITH ex_table AS ( SELECT ''2007-01-01'' ''birthdatetime'', ''2009-03-29'' ''visitdatetime'') SELECT CAST(DATEDIFF(yy, t.birthdatetime, t.visitdatetime) AS varchar(4)) +'' year ''+ CAST(DATEDIFF(mm, DATEADD(yy, DATEDIFF(yy, t.birthdatetime, t.visitdatetime), t.birthdatetime), t.visitdatetime) AS varchar(2)) +'' month ''+ CAST(DATEDIFF(dd, DATEADD(mm, DATEDIFF(mm, DATEADD(yy, DATEDIFF(yy, t.birthdatetime, t.visitdatetime), t.birthdatetime), t.visitdatetime), DATEADD(yy, DATEDIFF(yy, t.birthdatetime, t.visitdatetime), t.birthdatetime)), t.visitdatetime) AS varchar(2)) +'' day'' AS result FROM ex_table t

..o no CTE usando para SQL Server 2000 y anteriores:

SELECT CAST(DATEDIFF(yy, t.birthdatetime, t.visitdatetime) AS varchar(4)) +'' year ''+ CAST(DATEDIFF(mm, DATEADD(yy, DATEDIFF(yy, t.birthdatetime, t.visitdatetime), t.birthdatetime), t.visitdatetime) AS varchar(2)) +'' month ''+ CAST(DATEDIFF(dd, DATEADD(mm, DATEDIFF(mm, DATEADD(yy, DATEDIFF(yy, t.birthdatetime, t.visitdatetime), t.birthdatetime), t.visitdatetime), DATEADD(yy, DATEDIFF(yy, t.birthdatetime, t.visitdatetime), t.birthdatetime)), t.visitdatetime) AS varchar(2)) +'' day'' AS result FROM (SELECT ''2007-01-01'' ''birthdatetime'', ''2009-03-29'' ''visitdatetime'') t

... volverá:

result ---------------------- 2 year 2 month 28 day

Referencia: DATEDIFF


Consulte esta página ... http://www.sqlteam.com/article/datediff-function-demystified

Crea estas funciones:

CREATE FUNCTION dbo.fnYearsApart ( @FromDate DATETIME, @ToDate DATETIME ) RETURNS INT AS BEGIN RETURN CASE WHEN @FromDate > @ToDate THEN NULL WHEN DATEPART(day, @FromDate) > DATEPART(day, @ToDate) THEN DATEDIFF(month, @FromDate, @ToDate) - 1 ELSE DATEDIFF(month, @FromDate, @ToDate) END / 12 END

y

CREATE FUNCTION dbo.fnMonthsApart ( @FromDate DATETIME, @ToDate DATETIME ) RETURNS INT AS BEGIN RETURN CASE WHEN @FromDate > @ToDate THEN NULL WHEN DATEPART(day, @FromDate) > DATEPART(day, @ToDate) THEN DATEDIFF(month, @FromDate, @ToDate) - 1 ELSE DATEDIFF(month, @FromDate, @ToDate) END END

y finalmente

ALTER FUNCTION [dbo].[gatYMD](@dstart VARCHAR(50), @dend VARCHAR(50)) RETURNS VARCHAR(50) AS BEGIN DECLARE @yy INT DECLARE @mm INT DECLARE @dd INT DECLARE @getmm INT DECLARE @getdd INT SET @yy = dbo.fnYearsApart(@dstart, @dend) --DATEDIFF(yy, @dstart, @dend) SET @mm = dbo.fnMonthsApart(@dstart, @dend) --DATEDIFF(mm, @dstart, @dend) SET @dd = DATEDIFF(dd, @dstart, @dend) SET @getmm = ABS(DATEDIFF(mm, DATEADD(yy, @yy, @dstart), @dend)) SET @getdd = ABS(DATEDIFF(dd, DATEADD(mm, DATEDIFF(mm, DATEADD(yy, @yy, @dstart), @dend), DATEADD(yy, @yy, @dstart)), @dend)) RETURN ( Convert(varchar(10),@yy) + '' años, '' + Convert(varchar(10),@getmm) + '' meses, '' + Convert(varchar(10),@getdd) + '' días'' ) END

¡Grandes!


Funciona para algunas de las situaciones, pero cuando resta fechas como 2007-10-15 (DateHired) desde 2011-01-13 (fecha de finalización) le da un número negativo cuando los abdominales no están alrededor de él, pero poniendo los abdominales alrededor tampoco lo soluciona porque la cifra de año y mes es incorrecta.


Cree esta función, le dará la diferencia de fecha exacta como el año meses días

Create function get_Exact_Date_diff(@date smalldatetime,@date2 smalldatetime) returns varchar(50) as begin declare @date3 smalldatetime Declare @month int,@year int,@day int if @date>@date2 begin set @date3=@date2 set @date2=@date set @date=@date3 end SELECT @month=datediff (MONTH,@date,@date2) if dateadd(month,@month,@date) >@date2 begin set @month=@month-1 end set @day=DATEDIFF(day,dateadd(month,@month,@date),@date2) set @year=@month/12 set @month=@month % 12 return (case when @year=0 then '''' when @year=1 then convert(varchar(50),@year ) + '' year '' when @year>1 then convert(varchar(50),@year ) + '' years '' end) + (case when @month=0 then '''' when @month=1 then convert(varchar(50),@month ) + '' month '' when @month>1 then convert(varchar(50),@month ) + '' months '' end) + (case when @day=0 then '''' when @day=1 then convert(varchar(50),@day ) + '' day '' when @day>1 then convert(varchar(50),@day ) + '' days '' end) end


La función modificada

ALTER FUNCTION [dbo].[gatYMD](@dstart VARCHAR(50), @dend VARCHAR(50)) RETURNS VARCHAR(50) AS BEGIN DECLARE @yy INT DECLARE @mm INT DECLARE @getdd INT DECLARE @dd INT SET @yy = DATEDIFF(yy, @dstart, @dend) SET @mm = DATEDIFF(mm, @dstart, @dend) - (12 * @yy) SET @dd = ABS(DATEDIFF(dd, DATEADD(mm, DATEDIFF(mm, DATEADD(yy, @yy, @dstart), @dend), DATEADD(yy, @yy, @dstart)), @dend)) Return (Convert(varchar(10),@yy) + '' year '' + Convert(varchar(10),@mm) + '' month '' + Convert(varchar(10),@dd) + '' day '') END


Using ParseName DECLARE @ReportBeginDate DATE SET @ReportBeginDate=''2015-01-01''; IF OBJECT_ID(''TEMPDB..#tmp_ymd'') IS NOT NULL BEGIN DROP TABLE #tmp_ymd; END; select cast(cast(datediff(mm,@ReportBeginDate,getdate()) as decimal (10,2))/12 as decimal(10,2)) as YearMonthDec ,cast(datediff(dd,@ReportBeginDate,getdate()) as decimal (10,2)) as DayDec into #tmp_ymd select YearMonthDec ,cast(parsename(YearMonthDec,2) as decimal (10,0)) as yearnum ,cast(cast(parsename(YearMonthDec,1) as decimal (10,0))/100*(12) as numeric) as monthnum ,case when YearMonthDec>=1 then datediff(dd,CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(getdate())-1),getdate()),101),getdate()) else DayDec end as daynum from #tmp_ymd


Sé que ya hay algunas respuestas aquí, pero pensé que agregaría lo que se me ocurrió ya que (al menos para mí) parece muy simple de seguir:

CREATE FUNCTION dbo.fn_DateDiff_YMDMHS ( @Startdate as datetime2(0), @Enddate as datetime2(0) ) RETURNS TABLE AS RETURN ( select TotalYears [Years], datediff(month, dateadd(Year, TotalYears, @Startdate), @Enddate) Months, datediff(day, dateadd(month, TotalMonths, @Startdate), @Enddate) [Days], datediff(hour, dateadd(day, TotalDays, @Startdate), @Enddate) [Hours], datediff(minute, dateadd(hour, TotalHours, @Startdate), @Enddate) [Minutes], datediff(second, dateadd(minute, TotalMinutes, @Startdate), @Enddate) [Seconds] from ( select datediff(SECOND, @Startdate, @Enddate) TotalSeconds, datediff(minute, @Startdate, @Enddate) TotalMinutes, datediff(hour, @Startdate, @Enddate) TotalHours, datediff(day, @Startdate, @Enddate) TotalDays, datediff(month, @Startdate, @Enddate) TotalMonths, datediff(year, @Startdate, @Enddate) TotalYears) DateDiffs )

Luego cuando llamas con:

select * from dbo.fn_DateDiff_YMDMHS(''1900-01-01 00:00:00'', ''1910-10-05 03:01:02'')

Obtendrás esto devuelto:

Years Months Days Hours Minutes Seconds 10 9 4 3 1 2

Obviamente, podría cambiar esto a una salida formateada y tener una variable escalar en su lugar, pero se lo dejo a usted :-)

EDITAR:

Terminé necesitando también hacer una función de tiempo atrás para devolver un formato como "5 años y 2 días atrás"

CREATE FUNCTION fn_DateDiff_YMDMHS_String ( @StartDate datetime2(0), @EndDate datetime2(0), @OutputYears bit = 1, @OutputMonths bit = 1, @OutputDays bit = 1, @OutputHours bit = 0, @OutputMinutes bit = 0, @OutputSeconds bit = 0, @OutputSuffix bit = 0 ) RETURNS varchar(256) AS BEGIN DECLARE @Output varchar(256) = '''' declare @Years int, @Months int, @Days int, @Hours int, @Minutes int, @Seconds int select @Years = case when @OutputYears = 1 then Years else 0 end, @Months = case when @OutputMonths = 1 then Months else 0 end, @Days = case when @OutputDays = 1 then Days else 0 end, @Hours = case when @OutputHours = 1 then Hours else 0 end, @Minutes = case when @OutputMinutes = 1 then Minutes else 0 end, @Seconds = case when @OutputSeconds = 1 then Seconds else 0 end from dbo.fn_DateDiff_YMDMHS(@StartDate, @EndDate) declare @and varchar(5) = '''' if @OutputYears = 1 and @Years > 0 begin set @Output = @Output + cast(@Years as varchar(4)) + '' year'' if @Years > 1 set @Output = @Output + ''s '' else set @Output = @Output + '' '' if @Months > 0 and @Days + @Hours + @Minutes + @Seconds = 0 set @and = ''and '' end if @OutputMonths = 1 and @Months > 0 begin set @Output = @Output + @and + cast(@Months as varchar(2)) + '' month'' if @Months > 1 set @Output = @Output + ''s '' else set @Output = @Output + '' '' if @Days > 0 and @Hours + @Minutes + @Seconds = 0 set @and = ''and '' end if @OutputDays = 1 and @Days > 0 begin set @Output = @Output + @and + cast(@Days as varchar(2)) + '' day'' if @Days > 1 set @Output = @Output + ''s '' else set @Output = @Output + '' '' if @Hours > 0 and @Minutes + @Seconds = 0 set @and = ''and '' end if @OutputHours = 1 and @Hours > 0 begin set @Output = @Output + @and + cast(@Hours as varchar(2)) + '' hour'' if @Hours > 1 set @Output = @Output + ''s '' else set @Output = @Output + '' '' if @Minutes > 0 and @Seconds = 0 set @and = ''and '' end if @OutputMinutes = 1 and @Minutes > 0 begin set @Output = @Output + @and + cast(@Minutes as varchar(2)) + '' minute'' if @Minutes > 1 set @Output = @Output + ''s '' else set @Output = @Output + '' '' if @Seconds > 0 set @and = ''and '' end if @OutputSeconds = 1 and @Seconds > 0 begin set @Output = @Output + @and + cast(@Seconds as varchar(2)) + '' second'' if @Seconds > 1 set @Output = @Output + ''s '' else set @Output = @Output + '' '' end if @OutputSuffix = 1 begin if @StartDate < @EndDate begin set @Output = @Output + ''ago'' end else begin set @Output = ''in '' + @Output end end RETURN @Output END

Aquí hay 2 ejemplos

select dbo.fn_DateDiff_YMDMHS_String(''2000-01-01 00:00:00'', ''2007-09-19 14:39:53'', 1, 1, 1, 1,1,1, 1) 7 years 8 months 18 days 8 hours 39 minutes and 53 seconds ago

y

select dbo.fn_DateDiff_YMDMHS_String(''2000-01-01 00:00:00'', ''2007-09-19 14:39:53'', 1, 1, 1, 0,0,0, 1) 7 years 8 months and 18 days ago

Espero que esto sea de utilidad para alguien en el futuro de todos modos, ya que no pude encontrar mucho sobre esto cuando busqué (podría ser uno de esos días). Estoy abierto a las mejoras ya que sé que no soy siempre el programador de código más compacto o más rápido :-)

Saludos

Liam