我需要以下列方式计算两个日期(DateFrom
和DateTo
)之间的年,月,日格式的年龄:
DateFrom
中的某一天是第1天,则将其作为整月使用DateFrom
中的某一天不是第一天,则计算直到月底的天数。 示例:
在计算年龄后,我需要将年龄相加,假设月份是30天 - 在上面的例子中,我预计结果:2年,2个月,19天。
答案 0 :(得分:2)
我的假设是你有一个包含“ DateFrom ”和“ DateTo ”列的表格,所以查询将是这样的:
DECLARE @TotalDiffInDays int = (SELECT AVG(DATEDIFF(DAY, DateFrom, DateTo)) AS [TotalDays] FROM #t)
SELECT @TotalDiffInDays
DECLARE @DaysInMonth int = 30;
DECLARE @DaysInYear int = 365;
SELECT
@TotalDiffInDays / 365 AS AvgYearsDiff,
(@TotalDiffInDays / @DaysInMonth - @TotalDiffInDays / @DaysInYear * 12) AS AvgMonthsDiff,
@TotalDiffInDays - ((@TotalDiffInDays / 365) * @DaysInYear + (@TotalDiffInDays / @DaysInMonth - @TotalDiffInDays / @DaysInYear * 12) * @DaysInMonth) AS AvgDaysDiff
请注意,在这种情况下,我使用 INT 除法来获取正确的数字。
此外,如果您只想以上述格式获取日期差异,可以使用此查询:
SELECT
DATEDIFF(YEAR, DateFrom, DateTo) AS [Years],
-- Add year diff to get corret months diff
DATEDIFF(MONTH, DATEADD(YEAR, DATEDIFF(YEAR, DateFrom, DateTo), DateFrom), DateTo) AS [Months],
-- Add months diff to get correct days diff
DATEDIFF(DAY, DATEADD(MONTH, DATEDIFF(MONTH, DateFrom, DateTo), DateFrom), DateTo) AS [Days]
FROM #t
我希望这会有所帮助。
是的,只是忘记了你的第一天而不是一月的第一天的规则,你可以通过添加DATEPART(DAY,your_date)函数轻松修改这些查询,以检查它是否是该月的第一个日期并执行DETEADD ()应用此逻辑或只在AVG之前添加值1。
答案 1 :(得分:1)
因此,基本上自定义日期数学以来,您需要实现自己的函数以获得所需的结果。
参见下面的TSQL
CREATE FUNCTION dbo.getDateSum(@d1 varchar(100), @d2 varchar(100))
RETURNS varchar(100)
WITH EXECUTE AS CALLER
AS
BEGIN
DECLARE @y int, @m int, @d int
Select
@d1= REPLACE(REPLACE(REPLACE(@d1,' years, ', '-'),' months, ','-'),' days',''),
@d2= REPLACE(REPLACE(REPLACE(@d2,' years, ', '-'),' months, ','-'),' days','')
Select
@y= CAST(LEFT(@d1,CHARINDEX('-',@d1)-1) AS INT)+CAST(LEFT(@d2,CHARINDEX('-',@d2)-1) AS INT),
@m= CAST(SUBSTRING(@d1,CHARINDEX('-',@d1)+1,LEN(@d1)-CHARINDEX('-',REVERSE(@d1))-CHARINDEX('-',@d1))AS INT)+CAST(SUBSTRING(@d2,CHARINDEX('-',@d2)+1,LEN(@d2)-CHARINDEX('-',REVERSE(@d2))-CHARINDEX('-',@d2)) AS INT),
@d= CAST(LEFT(REVERSE(@d1),CHARINDEX('-',REVERSE(@d1))-1)AS INT)+CAST(LEFT(REVERSE(@d2),CHARINDEX('-',REVERSE(@d2))-1) AS INT)
IF(@d>30)
BEGIN
SET @d=@d%30
SET @m=@m+CAST(@d/30 as INT)
END
IF(@m>30)
BEGIN
SET @m=@m%12
SET @y=@y+CAST(@m/12 as INT)
END
RETURN (cast(@y as varchar)+ ' years, ' + cast(@m as varchar) +' months, '+ cast(@d as varchar) + ' days' );
END
go
CREATE FUNCTION dbo.getDateDiff(@df date, @dt date)
RETURNS varchar(100)
WITH EXECUTE AS CALLER
AS
BEGIN
declare @y int, @m int, @d int
Select @y= YEAR(@dt)- YEAR(@df),@m= MONTH(@dt)- MONTH(@df),@d=CASE WHEN DAY(@df)=1 THEN DAY(@dt)- DAY(@df)+1 ELSE DAY(@dt)- DAY(@df) -1 END
If (@d<0)
BEGIN
Set @m=@m-1
set @d=@d + DATEDIFF(d, @dt, EOMONTH(@dt))
END
IF(@m<0)
BEGIN
Set @y=@y-1
Set @m=@m+ 12
END
RETURN (cast(@y as varchar)+ ' years, ' + cast(@m as varchar) +' months, '+ cast(@d as varchar) + ' days' )
END
go
SELECT dbo.getDateSum(dbo.getDateDiff('2010-02-01','2011-03-11'),dbo.getDateDiff('2010-02-02', '2011-03-11'))
go