生成2个日期之间的日期范围

时间:2017-07-06 07:26:59

标签: sql sql-server azure-sql-database

在过去的几个小时里,我一直在为此而烦恼。

我想创建一个包含一系列日期的结果集:

2011-07-05
2011-07-04
2011-07-03
2011-07-02
2011-07-01
2011-06-30
2011-06-29
2011-06-28
...

理想情况是在两个日期之间给出。但如果我可以说过去30天或过去100天也没关系。

通常情况下,我会选择像这样的CTE

;WITH Dates AS
(
    SELECT CONVERT(DATE, GETDATE()) [Date]
    UNION ALL
    SELECT DATEADD(DAY,-1, [Date])
    FROM Dates
    WHERE [Date] > DATEADD(DAY, -30, CONVERT(DATE, GETDATE()))
)
SELECT [Date]

但我不允许使用任何不能在子查询中执行的语句。我正在使用的程序执行如下查询:

Select *
From (
    TheQuery
) as t1

这意味着我不能使用声明,没有存储过程,没有CTE ..

我有什么方法可以获得这些限制所需的数据集吗?

我正在使用azure SQL

4 个答案:

答案 0 :(得分:2)

如果将其放在表值函数

中,则可以使用递归cte
CREATE FUNCTION FnDateRange
(   
    @startDate date,
    @endDate date
)
RETURNS @DateRange Table
(myDate date)
AS
begin
    with Dates_rte as
    (
        select @startDate myDate
        union all
        select cast(dateadd(day,1,myDate) as date)
        from Dates_rte
        where cast(dateadd(day,1,myDate) as date) <= @endDate
    )
    insert into @DateRange
    select * from Dates_rte option (maxrecursion 0)

    return
end
GO

select * from fnDateRange('2017-07-01','2017-07-06')

答案 1 :(得分:1)

如果您不想创建日历表或数字表,也不要使用现有表来生成数字/日期(请参阅例如https://sqlperformance.com/2013/01/t-sql-queries/generate-a-set-1) 你可以使用这样的东西:

SELECT DATEADD(DAY, -B.N1+1, CONVERT(DATE, GETDATE())) AS D1
FROM 
(SELECT 1 AS N1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7  UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10) A
CROSS JOIN (SELECT 1 AS N1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7  UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10) B

答案 2 :(得分:1)

DECLARE @fromdate DATE
DECLARE @todate DATE
DECLARE @tcaldate Table (CalenderDate Date);

set @fromdate='2017-04-17'
set @todate='2017-05-13'

INSERT INTO @tcaldate SELECT  TOP (DATEDIFF(DAY, @fromdate, @todate) + 1)
        Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @fromdate)
FROM    sys.all_objects a
        CROSS JOIN sys.all_objects b;  

Select * from @tcaldate

希望这会有所帮助......

答案 3 :(得分:0)

嗯,我认为最简单的方法是创建日历表,在子查询中只选择日期之间的日期。 您可以通过此查询执行此操作:

CREATE TABLE dbo.Calendar ([Date] date)
DECLARE @startDate date, @endDate date

SET @startDate = '2000-01-01'
SET @endDate = '2020-12-31'

WHILE @startDate <= @endDate
BEGIN
INSERT INTO dbo.Calendar
SELECT @startDate

SET @startDate = DATEADD(DD,1,@startDate)
END

选择日期:

Select *
From dbo.Calendar WHERE [Date] BETWEEN @date1 AND @date2