所有人
我希望外面有人可以帮助我获得相同的结果,并消除这种递归CTE。从原则上讲,这听起来很简单,但是我已经为此工作了至少两天,什么也没想出来。最后一件事,我知道OPTION(MAXRECURSION 0)选项。这对我们来说不是可行的选择。我们处于生产环境中,不希望对数据库进行爬网。如果可能的话,我们希望摆脱递归CTE。
WITH cte AS
(
SELECT DATEADD(month, DATEDIFF(month, 0, @StartDate), 0) AS StartOfMonth,
DATEADD(s, 0, DATEADD(mm, DATEDIFF(m, 0, @StartDate) + 1, 0)) AS EndOfMonth
UNION ALL
SELECT DATEADD(month, 1, StartOfMonth) AS StartOfMonth,
DATEADD(s, 0, DATEADD(mm, DATEDIFF(m, 0, DATEADD(month, 1, StartOfMonth)) + 1, 0)) AS EndOfMonth
FROM cte
WHERE DATEADD(month, 1, StartOfMonth) <= @EndDate
)
上面的代码位于SQL Server中名为fn_SplitPeriodIntoMonths的表值函数中。
一个可以调用该函数的
SELECT * FROM fn_SplitPeriodIntoMonths('2018-01-01','2018-09-01')
然后结果就是这个
StartOfMonth EndOfMonth
2018-01-01 00:00:00.000 2018-02-01 00:00:00.000
2018-02-01 00:00:00.000 2018-03-01 00:00:00.000
2018-03-01 00:00:00.000 2018-04-01 00:00:00.000
2018-04-01 00:00:00.000 2018-05-01 00:00:00.000
2018-05-01 00:00:00.000 2018-06-01 00:00:00.000
2018-06-01 00:00:00.000 2018-07-01 00:00:00.000
2018-07-01 00:00:00.000 2018-08-01 00:00:00.000
2018-08-01 00:00:00.000 2018-09-01 00:00:00.000
2018-09-01 00:00:00.000 2018-10-01 00:00:00.000
您可以看到结果是按月细分的期间。挺酷的。然后,人们可以以多种方式使用它。但是,如果使用行太多的选择来调用它,我们将达到MAXRECUSION LIMIT。
任何帮助将不胜感激。
祝一切顺利,
乔治
答案 0 :(得分:2)
/****** Object: UserDefinedFunction [dbo].[fn_SplitPeriodIntoMonths] Script Date: 24/07/2018 17:29:05 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Andy Deighton
-- Create date: 24/07/2018
-- Description: Return a date table
-- =============================================
ALTER FUNCTION [dbo].[fn_SplitPeriodIntoMonths]
(
-- Add the parameters for the function here
@START DATE,
@END DATE
)
RETURNS TABLE
AS
RETURN
(
SELECT AM.StartOfMonth, EOMONTH(AM.StartOfMonth) EndOfMonth FROM
(
SELECT datefromparts(100 * (c.century - 1) + 10 * (d.decade -1) + y.[year],M.[month],1) StartOfMonth
FROM
(SELECT 20 century UNION SELECT 21) C
CROSS JOIN
(SELECT decade FROM
(VALUES (1), (2), (3), (4), (5), (6),(7),(8),(9), (10))
X(decade)) D
CROSS JOIN
(SELECT [year] FROM
(VALUES (0), (1), (2), (3), (4), (5),(6),(7),(8), (9))
X([year])) Y
CROSS JOIN
(SELECT [month] FROM
(VALUES (1), (2), (3), (4), (5),(6),(7),(8), (9), (10), (11),(12))
X([month])) M
) AM WHERE AM.StartOfMonth BETWEEN @START AND @END
)
示例通话
select * from dbo.fn_SplitPeriodIntoMonths('19660101','20450101') order by startofmonth