I'm trying to use this ExplodeDate function.
But I dont't get it run with one easy query. I can reproduce this with an empty database on SQL Server 2016 locally and in an Azure Database.
Please use following code to reproduce the issue.
Code for used functions:
/*
FUNCTION: [dbo].[ExplodeDates]
*/
DROP FUNCTION IF EXISTS [dbo].[ExplodeDates]
GO
CREATE FUNCTION [dbo].[ExplodeDates](@startdate datetime, @enddate datetime)
returns table as
return (
with
N0 as (SELECT 1 as n UNION ALL SELECT 1)
,N1 as (SELECT 1 as n FROM N0 t1, N0 t2)
,N2 as (SELECT 1 as n FROM N1 t1, N1 t2)
,N3 as (SELECT 1 as n FROM N2 t1, N2 t2)
,N4 as (SELECT 1 as n FROM N3 t1, N3 t2)
,N5 as (SELECT 1 as n FROM N4 t1, N4 t2)
,N6 as (SELECT 1 as n FROM N5 t1, N5 t2)
,nums as (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) as num FROM N6)
SELECT DATEADD(day,num-1,@startdate) as [Date]
FROM nums
WHERE num <= DATEDIFF(day,@startdate,@enddate) + 1
);
GO
/*
FUNCTION: [dbo].[ExplodeDatesByPeriod]
*/
DROP FUNCTION IF EXISTS [dbo].[ExplodeDatesByPeriod]
GO
CREATE FUNCTION [dbo].[ExplodeDatesByPeriod]
(
@StartDate DATE = '20130101',
@EndDate DATE ='20301231',
@ImpactPeriod INT = 4 -- 4 Jahr, 3 Quartal, 2 Monat, 1 Woche, 0 Tag - siehe ImpactPeriod
)
RETURNS TABLE
AS
RETURN(
WITH CTE
AS
(
SELECT
[Date]
, CASE
WHEN @ImpactPeriod = 0 THEN DATEPART(YEAR, [Date])
-- MORE WHEN CASES HERE ....
ELSE Year([Date])
END AS [Year]
, CASE
WHEN @ImpactPeriod = 0 THEN DATEPART(DAYOFYEAR, [Date])
-- MORE WHEN CASES HERE ....
ELSE Year([Date])
END AS [Period]
FROM [dbo].[ExplodeDates](CASE
WHEN @ImpactPeriod = 0 THEN @StartDate
-- MORE WHEN CASES HERE ....
ELSE DATEFROMPARTS(YEAR(@StartDate), 1, 1)
END, @EndDate)
)
SELECT
MIN([Date]) AS [StartOfPeriod]
, CASE
WHEN @ImpactPeriod = 0 THEN MIN([Date])
-- MORE WHEN CASES HERE ....
ELSE DATEFROMPARTS(DATEPART(YEAR, MIN([Date])), 12, 31)
END AS [EndOfPeriod]
, ([Year] * ( CASE
WHEN @ImpactPeriod = 0 THEN 1000
-- MORE WHEN CASES HERE ....
ELSE 0
END)
) + [Period] AS [YearPeriod]
, [Year]
, [Period]
FROM [CTE]
GROUP BY
[Year]
, [Period]
)
GO
Then if you run following code it never ends:
/*
TABLE WITH DUMMY DATA
*/
DROP TABLE IF EXISTS [T1]
CREATE TABLE [T1](
[StartDate] DATE,
[EndDate] DATE
)
INSERT INTO [T1] VALUES ('20190101', '20190101')
GO
/*
FUNCTION CALL TO: [dbo].[ExplodeDates] DOESN'T WORK!!
*/
SELECT * FROM [T1] CROSS APPLY [dbo].[ExplodeDates]([T1].[StartDate], [T1].[EndDate]) [D]
GO
The interesting thing is, that following query executes immediately:
/*
FUNCTION CALL TO: [dbo].[ExplodeDatesByPeriod] THIS WORKS!!
PARAM 0 for Days
*/
SELECT * FROM [T1] CROSS APPLY [dbo].[ExplodeDatesByPeriod]([T1].[StartDate], [T1].[EndDate], 0) [D]
GO
[dbo].[ExplodeDatesByPeriod] is calling [dbo].[ExplodeDates] internally!