如何选择两个日期之间的所有时间?

时间:2014-11-27 00:59:21

标签: sql sql-server tsql

declare @minDateTime as datetime;
declare @maxDateTime as datetime;

set @minDateTime = '2014-01-13 02:00:00';
set @maxDateTime = '2014-12-31 14:00:00';

我希望创建一个select语句,它将在@minDateTime和@maxDateTime之间每小时返回一次(没有可供选择的表。我不是在寻找where子句!):

2014-01-13 02:00:00
2014-01-13 03:00:00
2014-01-13 04:00:00
...
2014-12-31 12:00:00
2014-12-31 13:00:00
2014-12-31 14:00:00

2 个答案:

答案 0 :(得分:10)

试试这个。使用Recursive CTE

DECLARE @minDateTime AS DATETIME;
DECLARE @maxDateTime AS DATETIME;

SET @minDateTime = '2014-01-13 02:00:00';
SET @maxDateTime = '2014-12-31 14:00:00';

;
WITH Dates_CTE
     AS (SELECT @minDateTime AS Dates
         UNION ALL
         SELECT Dateadd(hh, 1, Dates)
         FROM   Dates_CTE
         WHERE  Dates < @maxDateTime)
SELECT *
FROM   Dates_CTE
OPTION (MAXRECURSION 0) 

在上面的查询中Dates_CTECommon Expression TableCTE的基本记录是由UNION ALL之前的第一个SQL查询派生的。查询结果为您提供Minimum date

重复执行UNION ALL后的第二次查询以获得结果。 此过程为 recursive ,并将持续到日期小于@maxDateTime

答案 1 :(得分:2)

以下是使用Tally Table的另一种方式:

DECLARE @minDateTime DATETIME;
DECLARE @maxDateTime DATETIME;

SET @minDateTime = '2014-01-13 02:00:00';
SET @maxDateTime = '2014-12-31 14:00:00';

DECLARE @hrsDiff INT;
SELECT @hrsDiff = DATEDIFF(HH, @minDateTime, @maxDateTime);

WITH E1(N) AS (
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
),--10E+1 or 10 rows
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
Tally(N) AS(SELECT row_number() over(order by (select null)) from E4) -- Numbered rrow
SELECT @minDateTime 
UNION ALL
SELECT DATEADD(HH, N, @minDateTime)
FROM Tally
WHERE
    N <= @hrsDiff