stephen.lightfoot - Tuesday, March 28, 2017 3:48 AM
ALTER FUNCTION [dbo].[il_ElapsedTime]
/*
Calculate the elapsed time between two datetimes
as year, month, day, hour, minute, second, millisecond
such that adding these values using DATEADD to the earlier
value will yield the later value.
This also calculates AGE.
*/
(@Then DATETIME, @Now DATETIME)
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
SELECT
ds.Years,
mo.Months,
ds.[Days],
r.[Hours],
r.[Minutes],
r.Seconds,
r.Milliseconds
FROM (
SELECT
[Days] = CASE
WHEN DAY(@Now) >= DAY(@Then) THEN DAY(@Now) - DAY(@Then)
ELSE DAY(@Now) + (DATEDIFF(DAY,@Then,EOMONTH(@Then)))
END,
[Years] = (0 + CONVERT(CHAR(8),@Now,112) - CONVERT(CHAR(8),@Then,112)) / 10000
) ds
CROSS APPLY (SELECT [Months] = DATEDIFF(month,DATEADD(YEAR,[Years],DATEADD(day,[Days],@Then)),@Now)) mo
CROSS APPLY (Here's a test harness too:SET NOCOUNT ON
IF OBJECT_ID('TempDB..#DOBs') IS NULL BEGIN
DECLARE @Today DATETIME = GETDATE()-13
SELECT DOB = DATEADD(DAY,1-ROW_NUMBER() OVER(ORDER BY (SELECT NULL)),CAST(@Today AS DATETIME))
INTO #DOBs
FROM
(VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) d1 (n),
(VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) d2 (n),
(VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) d3 (n),
(VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) d4 (n),
(VALUES (0),(0),(0),(0),(0)) d5 (n)
CREATE UNIQUE CLUSTERED INDEX ucx_Stuff ON #DOBs (DOB)
END
SELECT
d.DOB,
Today = @Today,
x1.*,
NewDate =
DATEADD(YEAR,x1.Years,
DATEADD(MONTH,x1.Months,
DATEADD(DAY,x1.[Days],
DATEADD(HOUR,x1.[Hours],
DATEADD(MINUTE,x1.[Minutes],
DATEADD(SECOND,x1.[Seconds],
DATEADD(MILLISECOND,x1.[Milliseconds],d.DOB)))))))
FROM #DOBs d
CROSS APPLY [dbo].[il_ElapsedTime] (d.DOB, @Today) x1
-- Without the NewDate calculation and with rows blackholed
-- into variables; 50,000 rows in about half a second (SET STATISTICS TIME)
Edit: Sorry, but the code display seems to be completely haywire today. If I enter EDIT mode, the code tags look fine.
For fast, accurate and documented assistance in answering your questions, please read this article.
Understanding and using APPLY, (I) and (II) Paul White
Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden