获取开始日期和结束日期之间的日期

时间:2018-08-21 14:51:04

标签: sql sql-server date

嗨,我有一个问题。

我需要能够使用SQL查询根据开始和结束日期以月为单位查找日期。 即。开始日期:2013-08-01 00:00:00.000,结束日期:2015-08-01 00:00:00.000 结果必须如下:

2013-08-01 00:00:00.000,
2013-09-01 00:00:00.000,
2013-10-01 00:00:00.000,
2013-11-01 00:00:00.000,
2013-12-01 00:00:00.000,
2014-01-01 00:00:00.000,
2014-02-01 00:00:00.000,
2014-03-01 00:00:00.000,
2014-04-01 00:00:00.000,
2014-05-01 00:00:00.000,
2014-06-01 00:00:00.000,
2014-07-01 00:00:00.000,
2014-08-01 00:00:00.000,
2014-09-01 00:00:00.000,
2014-10-01 00:00:00.000,
2014-11-01 00:00:00.000,
2014-12-01 00:00:00.000,
2015-01-01 00:00:00.000,
2015-02-01 00:00:00.000,
2015-03-01 00:00:00.000,
2015-04-01 00:00:00.000,
2015-05-01 00:00:00.000,
2015-06-01 00:00:00.000,
2015-07-01 00:00:00.000,
2015-08-01 00:00:00.000

请您帮忙。 预先感谢

3 个答案:

答案 0 :(得分:2)

如果是我,我会做一个Calendar表。当然,您可以使用datediff进行很多精美的SQL处理,但是不行,但是将具有100年日期的表加入其中似乎总是非常方便。如果您要使用数据中的日期做很多事情,那真是太好了。这样做确实有点“便宜”,但对我来说效果很好。

How to create a Calendar table for 100 years in Sql

然后,您只需加入此列表,即可获取该范围内的日期。

更新

@scsimon指出,链接中可接受的答案可能不是理想的。不过,请给该链接进行阅读,并在那里准备一些好的想法。

答案 1 :(得分:2)

理货桌子真的很快...

WITH
    E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
    E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
    E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
    cteTally(N) AS 
    (
        SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
    )

select '20130801'
union all
select dateadd(month,N,'20130801') 
from cteTally
where n <= datediff(month,'20130801','20150801')

更清楚地使用参数

declare @startDate date = '20130801'
declare @endDate date = '20150801'

;WITH
    E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
    E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
    E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
    cteTally(N) AS 
    (
        SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
    )

select @startDate
union all
select dateadd(month,N,@startDate) 
from cteTally
where n <= datediff(month,@startDate,@endDate)

答案 2 :(得分:1)

有许多解决方法。我经常使用的是递归CTE:

DECLARE @StartDate      date = '2013-08-01'
DECLARE @EndDate        date = '2015-08-01'

;WITH
    cte AS
    (
        SELECT      @StartDate      AS CalendarDate
        UNION ALL
        SELECT      DATEADD(MONTH, 1, CalendarDate)
        FROM        cte
        WHERE       CalendarDate < @EndDate
    )

SELECT      CalendarDate
FROM        cte
OPTION      (MAXRECURSION 0)

对于较小的值范围(12个月x 100年很小),这非常快。当您需要获得数百万行时,它变得很慢。根据眼前的问题,您可能需要其他解决方案。