-3

我想datetime在 SQL Server 2000 中生成范围。我想要与 2000、2005 和 2008 兼容的东西。如果它与 2012 兼容,那就太好了。

所以,我在这里找到了答案——在日期范围之间生成日期。但是,我想要两列而不是 1。我想要一个开始日期列和一个结束日期列。如何修改下面的查询以获取它?

-- Declarations

DECLARE @dates TABLE(dt datetime)    
DECLARE @dateFrom datetime
DECLARE @dateTo datetime

SET @dateFrom = '2001/01/01'
SET @dateTo = '2001/01/12'

-- Query:

WHILE(@dateFrom < @dateTo)
BEGIN
   SELECT @dateFrom = DATEADD(day, 1,@dateFrom)
   INSERT INTO @dates 
   SELECT @dateFrom
END

-- Output

SELECT * FROM @dates

我的代码 -

DECLARE @dates TABLE(StartDate datetime, EndDate datetime)    
DECLARE @dateFrom datetime
DECLARE @dateTo datetime
DECLARE @StartDate datetime
DECLARE @EndDate datetime

SET @dateFrom = '2001/01/01'
SET @dateTo = '2001/01/12'

WHILE(@dateFrom < @dateTo)
BEGIN
   SELECT @dateFrom, @dateFrom = DATEADD(day, 1,@dateFrom)
   INSERT INTO @dates 
   SELECT @dateFrom
END

SELECT * FROM @dates

错误 - 为变量赋值的 SELECT 语句不得与数据检索操作结合使用。

4

3 回答 3

5

这是一个基于集合的解决方案,它使用spt_values2000 -> 2014 的所有 SQL Server 版本中的系统表。在 2000 年,这将限制为 256 天的日期范围。在更现代的版本中,此上限为 2048。

通常,基于集合的解决方案比任何类型的WHILE循环都更有效。

DECLARE @start DATETIME, @end DATETIME;

SELECT @start = '20010101', @end = '20010112';

-- INSERT @dates(StartDate, EndDate)
SELECT 
  StartDate = DATEADD(DAY, number,   @start), 
  EndDate   = DATEADD(DAY, number+1, @start)
FROM master..spt_values 
WHERE [type] = 'p' 
AND number < DATEDIFF(DAY, @start, @end);

也就是说,特别是考虑到 256 天的限制,您应该只考虑自己的数字和/或日历表来绕过这个限制:

http://www.sqlperformance.com/generate-a-set-1

http://www.sqlperformance.com/generate-a-set-2

http://www.sqlperformance.com/generate-a-set-3

因此,您可以使用以下代码创建一个(假设 100,000 天对您来说足够大):

SELECT TOP 100000 Number = IDENTITY(INT,1,1) 
INTO dbo.Numbers 
FROM sysobjects AS s1 
CROSS JOIN sysobjects AS s2
ORDER BY 1;

CREATE UNIQUE CLUSTERED INDEX n ON dbo.Numbers(Number);

以上在我的 2000 系统上花费了 4.2 秒。创建该表后,查询变得更加容易(并且限制更少):

DECLARE @start DATETIME, @end DATETIME;

SELECT @start = '20010101', @end = '20010112';

-- INSERT @Dates(StartDate, EndDate)
SELECT 
  StartDate = DATEADD(DAY, Number-1, @start), 
  EndDate   = DATEADD(DAY, Number,   @start)
FROM dbo.Numbers 
WHERE Number <= DATEDIFF(DAY, @start, @end); 
于 2013-11-12T21:46:56.663 回答
0

这使用了一个数字表:

DECLARE @dateFrom datetime, @dateTo datetime

SELECT @dateFrom = '2001/01/01'
      ,@dateTo = '2001/01/12'

select
    @dateFrom+Number-1
    From Numbers
    WHERE Number<=datediff(day,@dateFrom,@dateTo+1)

输出:

-----------------------
2001-01-01 00:00:00.000
2001-01-02 00:00:00.000
2001-01-03 00:00:00.000
2001-01-04 00:00:00.000
2001-01-05 00:00:00.000
2001-01-06 00:00:00.000
2001-01-07 00:00:00.000
2001-01-08 00:00:00.000
2001-01-09 00:00:00.000
2001-01-10 00:00:00.000
2001-01-11 00:00:00.000
2001-01-12 00:00:00.000

(12 row(s) affected)

我不确定 OP 想要什么“2”列,但在查询中很容易:

select
    @dateFrom+Number-1,@dateFrom+Number
    From Numbers
    WHERE Number<=datediff(day,@dateFrom,@dateTo)

输出:

----------------------- -----------------------
2001-01-01 00:00:00.000 2001-01-02 00:00:00.000
2001-01-02 00:00:00.000 2001-01-03 00:00:00.000
2001-01-03 00:00:00.000 2001-01-04 00:00:00.000
2001-01-04 00:00:00.000 2001-01-05 00:00:00.000
2001-01-05 00:00:00.000 2001-01-06 00:00:00.000
2001-01-06 00:00:00.000 2001-01-07 00:00:00.000
2001-01-07 00:00:00.000 2001-01-08 00:00:00.000
2001-01-08 00:00:00.000 2001-01-09 00:00:00.000
2001-01-09 00:00:00.000 2001-01-10 00:00:00.000
2001-01-10 00:00:00.000 2001-01-11 00:00:00.000
2001-01-11 00:00:00.000 2001-01-12 00:00:00.000

如果您需要创建数字表,请参阅:创建和填充数字表的最佳方法是什么?

于 2013-11-12T21:45:38.483 回答
-4
-- Declarations

DECLARE @dates TABLE(dt datetime, dt2 datetime)    
DECLARE @dateFrom datetime
DECLARE @dateTo datetime
DECLARE @endDate datetime

SET @dateFrom = '2001/01/01'
SET @dateTo = '2001/01/12'

-- Query:

WHILE(@dateFrom < @dateTo)
BEGIN
   SELECT @dateFrom = DATEADD(day, 1,@dateFrom)
   SELECT @endDate = DATEADD(day, 1,@dateFrom)
   INSERT INTO @dates 
   SELECT @dateFrom, @endDate
END

-- Output

SELECT * FROM @dates
于 2013-11-12T21:44:06.867 回答