SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO /* 名称:[dbo].[f_getDateIntervalMulti] 功能:根据2个日期,计算年月日的差值 测试用例: select [dbo].[f_getDateIntervalMulti] ('2022-01-01','2022-06-30','Y',2) */ CREATE FUNCTION [dbo].[f_getDateIntervalMulti] (@d1 AS DATETIME,--开始日期 @d2 AS DATETIME,--结束日期 @type VARCHAR(10),--年月日Y,M,D @flag INT--保留小数位0,2,4 ) RETURNS NVARCHAR(100) AS BEGIN --函数默认@d1 <= @d2,如果@d1 > @d2,则交换 IF @d1 > @d2 BEGIN DECLARE @d3 AS DATETIME SET @d3 = @d1 SET @d1 = @d2 SET @d2 = @d3 END DECLARE @yy AS INT, @mm AS INT, @dd AS INT --先直接判断月数,每年的12个月是固定的 SET @mm = Datediff(MONTH, @d1, @d2) --当@d1的日大于@d2+1的日(不到1个月),则月份-1 IF Day(@d1) > Day(@d2) + 1 BEGIN SET @mm = @mm - 1 END --将@d1日期直接增加已获得的月数,以便后面直接判断天数 SET @d1 = Dateadd(MONTH, @mm, @d1) --根据@mm,获取年数 SET @yy = @mm / 12 --根据@mm,将@mm取余数,获取月数 SET @mm = @mm % 12 --获取@dd的天数,此时的@d1已经是接近@d2日期了 SET @dd = Datediff(DAY, @d1, @d2) + 1 --将@d1日期增加1个月,并减去1天,判断是否与@d2相同(满月判断) SET @d1 = Dateadd(MONTH, 1, @d1) SET @d1 = Dateadd(DAY, -1, @d1) --如果相同,则表示天数进位(满月),日期进位,月份+1 IF @d1 = @d2 BEGIN SET @mm = @mm + 1 SET @dd = 0 END --最后也是判断月数是否有进位。判断@mm是否为12(逢12进1),如果是则年份+1,即@yy+1,然后@mm设为0 IF @mm = 12 BEGIN SET @yy = @yy + 1 SET @mm = 0 END DECLARE @num DECIMAL(18, 8) DECLARE @str AS NVARCHAR(100) SET @str='' IF @type = 'Y' BEGIN SET @num=@yy + @mm / 12.0 + @dd / 365.0 END IF @type = 'M' BEGIN SET @num=@yy * 12 + @mm + @dd / 30.0 END IF @type = 'D' BEGIN SET @num=@yy * 365 + @mm * 30 + @dd END IF @flag = 0 BEGIN SET @str=CONVERT(VARCHAR(100), CONVERT(DECIMAL(18, 0), @num)) END ELSE IF @flag = 4 BEGIN SET @str=CONVERT(VARCHAR(100), CONVERT(DECIMAL(18, 4), @num)) END ELSE BEGIN SET @str=CONVERT(VARCHAR(100), CONVERT(DECIMAL(18, 2), @num)) END RETURN @str END