The existing answers are outdated for current versions of SQL Server, since there are much more elegant ways to do this today. In case the following question gets closed to point here, I wanted to make sure this post had a modern answer as well.
On SQL Server 2022 (or Azure SQL DB/MI), you can use GENERATE_SERIES
:
DECLARE @start datetime = '20140113 02:00:00',
@end datetime = '20141231 14:00:00';
SELECT h = DATEADD(HOUR, value, @start)
FROM GENERATE_SERIES(0, DATEDIFF(HOUR, @start, @end)) AS x;
On SQL Server 2016 or better, you can use STRING_SPLIT(REPLICATE
:
DECLARE @start datetime = '20140113 02:00:00',
@end datetime = '20141231 14:00:00';
SELECT h = DATEADD(HOUR, ROW_NUMBER() OVER (ORDER BY @@SPID)-1, @start)
FROM STRING_SPLIT
(REPLICATE(CONVERT(varchar(max), ','),
DATEDIFF(HOUR, @start, @end)), ',') AS x;
On older versions, the other answers here will work.
Here's a db<>fiddle but with a shorter date range because it doesn't gracefully handle thousands of output rows.