如果@EndDate在2015年内设置为任何内容,则下面的代码可以使用,但是当它是@StartDate日历年之后的日期时,它将在2015年3月12日停止。有人可以帮助我,我希望能够使用它来在用户定义的日期范围之间使用所有月份。
DECLARE @StartDate DATE
DECLARE @EndDate DATE
set @StartDate = '1/1/2015'
set @EndDate = '12/31/2016'
SELECT
cast(dateadd(m, month-1, @StartDate) as date) begin_month,
cast(dateadd(m, month, dateadd(year, datediff(year, 0, @StartDate), -1)) as date) end_month
FROM (values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)) x(month)
WHERE
cast(dateadd(m, month-1, @StartDate) as date) >= @StartDate
and
cast(dateadd(m, month, dateadd(year, datediff(year, 0, @EndDate), -1)) as date) <= @EndDate
答案 0 :(得分:2)
你几乎就在那里。不要只使用12行,而是尝试使用更多行。在这里,我创建了一个最多10,000行的Tally Table。然后,使用TOP
来限制行数,具体取决于DATEDIFF(MONTH, @StartDate, @EndDate) + 1
。有了它,您不再需要添加WHERE
子句:
DECLARE @StartDate DATE,
@EndDate DATE
SELECT @StartDate = '20150101',
@EndDate = '20161231'
;WITH E1(N) AS( -- 10 ^ 1 = 10 rows
SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N)
),
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b), -- 10 ^ 2 = 100 rows
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b), -- 10 ^ 4 = 10,000 rows
CteTally(N) AS(
SELECT TOP(DATEDIFF(MONTH, @startDate, @endDate) + 1)
ROW_NUMBER() OVER(ORDER BY(SELECT NULL))
FROM E4
)
SELECT
begin_month = DATEADD(MONTH, N-1, @startDate),
end_month = DATEADD(DAY, -1, DATEADD(MONTH, N, @startDate))
FROM CteTally