SQL查询返回一个表,其中每一行代表一个给定范围内的日期
时间:2020-03-06 15:04:07 来源:igfitidea点击:
是否可以创建一个SQL查询,该查询将返回一列,其中包含给定日期范围内的日期(例如,从去年到今天的所有日期)。例如。
dat ---- 2007-10-01 2007-10-02 2007-10-03 2007-10-04 ...
我想知道这是否可以替代创建包含所有预先计算的日期的表。
更新:我需要MYSQL解决方案。在这种情况下,我对其他任何数据库都不感兴趣。
解决方案
AFAIK,我们不能使用单个SQL查询来执行此操作。但是,下面的代码块将完成此工作。
当前在Transact-SQL中(对于SQL Server)。我不知道这如何转换成MySQL。
DECLARE @start datetime DECLARE @end datetime DECLARE @results TABLE ( val datetime not null ) set @start = '2008-10-01' set @end = getdate() while @start < @end begin insert into @results values(@start) SELECT @start = DATEADD (d, 1, @start) end select val from @results
输出:
2008-10-01 00:00:00.000 2008-10-02 00:00:00.000 2008-10-03 00:00:00.000
在进行CTE之前,可以使用标准的预加载整数表(通常在实用程序表中有几千个表,请参见本文),并根据需要加入该表。这将在mysql中为我们工作:
CREATE TABLE dbo.Numbers ( Number INT IDENTITY(1,1) PRIMARY KEY CLUSTERED ) WHILE COALESCE(SCOPE_IDENTITY(), 0) <= 1024 BEGIN INSERT dbo.Numbers DEFAULT VALUES END SELECT DATEADD(dd, Number, DATEADD(dd, 0, DATEDIFF(dd, 0, DATEADD(yy, -1, GETDATE())))) AS Date FROM Numbers WHERE Number BETWEEN 0 AND 366
在SQL Server 2005中,可以使用公用表表达式和递归:
WITH DateRange(Date) AS ( SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, DATEADD(yy, -1, GETDATE()))) AS Date UNION ALL SELECT DATEADD(day, 1, Date) AS Date FROM DateRange WHERE Date <= GETDATE() ) SELECT Date FROM DateRange OPTION (MAXRECURSION 366)
我暂时没有一个MySQL实例,但是看看是否可以。适当替换参数。我将代码硬编码为2007年1月1日。
问候。
SELECT ADDDATE('2007-01-01' INTERVAL SeqValue DAY) DateValue FROM ( SELECT (HUNDREDS.SeqValue + TENS.SeqValue + ONES.SeqValue) SeqValue FROM ( SELECT 0 SeqValue UNION ALL SELECT 1 SeqValue UNION ALL SELECT 2 SeqValue UNION ALL SELECT 3 SeqValue UNION ALL SELECT 4 SeqValue UNION ALL SELECT 5 SeqValue UNION ALL SELECT 6 SeqValue UNION ALL SELECT 7 SeqValue UNION ALL SELECT 8 SeqValue UNION ALL SELECT 9 SeqValue ) ONES CROSS JOIN ( SELECT 0 SeqValue UNION ALL SELECT 10 SeqValue UNION ALL SELECT 20 SeqValue UNION ALL SELECT 30 SeqValue UNION ALL SELECT 40 SeqValue UNION ALL SELECT 50 SeqValue UNION ALL SELECT 60 SeqValue UNION ALL SELECT 70 SeqValue UNION ALL SELECT 80 SeqValue UNION ALL SELECT 90 SeqValue ) TENS CROSS JOIN ( SELECT 0 SeqValue UNION ALL SELECT 100 SeqValue UNION ALL SELECT 200 SeqValue UNION ALL SELECT 300 SeqValue UNION ALL SELECT 400 SeqValue UNION ALL SELECT 500 SeqValue UNION ALL SELECT 600 SeqValue UNION ALL SELECT 700 SeqValue UNION ALL SELECT 800 SeqValue UNION ALL SELECT 900 SeqValue ) HUNDREDS ) SEQ WHERE SEQ.SeqValue < = 366 AND ADDDATE('2007-01-01' INTERVAL SeqValue DAY) < ADDDATE('2007-01-01' INTERVAL 1 YEAR) ORDER BY ADDDATE('2007-01-01' INTERVAL SeqValue DAY) ASC