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