因此,对于如何快速有效地生成日期列表而没有循环等问题,我现在已经在多个答案中看到了它。该公式有效,我已经将其复制,测试,使用了,等等。问题是,我只是不了解其背后的数学原理。我讨厌使用我不了解的东西,我觉得自己是A)作弊,B)之后会为遇到的问题做好准备。
无论如何,这是我正在谈论的公式:
set @start_date = '2015-9-20'; set @end_date = '2016-9-20'; select @start_date + interval ((a.a) + (10 * b.a) + (100 * c.a)) day as this_date from (select 0 as a union all select 1 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) as a cross join (select 0 as a union all select 1 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) as b cross join (select 0 as a union all select 1 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) as c;
快速说明:start_date / end_date东西只适合我。我最终将把它变成一个使用这两个值来生成日期范围的过程,这里的值只是我解决此问题时的测试值。
因此,让我们从我真正理解的部分开始,然后继续进行其他所有工作。
1)并集实际上是创建3个10行的表,其整数值为0-9。
2)3个表在没有指定where子句的情况下连接在一起,这意味着它是笛卡尔连接,并且行数呈指数增长(10 x 10 x 10 = 1000)。
3)日期值将以等于INTERVAL语句旁边括号内的值的天数间隔递增。
4)数学模式反映了笛卡尔联接。第一个表的每个值乘以1,第二个表乘以10,第三个表乘以100。
我不明白的是:数学本身。通过某种方式,通过将这些数字加在一起,结果是一个间隔,最终使日期的值增加了1000天。我只是想真正理解为什么它行之有效,除了模式之外,还包括真正的数学,程序化原因。
提前非常感谢。
您尝试做的是在两个日期之间生成一个范围。
通常,您可以使用循环for,while但不能与普通选择一起使用,并且需要存储过程。
for
while
当您意识到选择生成编号从0到999。
因此,您可以生成将近3年的日期。您得到的是:
@start_date + 1 day @start_date + 2 days @start_date + 3 days ... @start_date + 999 days
但是您的查询错过了哪里
WHERE @start_date + interval ((a.a) + (10 * b.a) + (100 * c.a)) <= @end_date
假设您要创建小时数范围,则需要添加另一个表格以将范围增加到0.. 9999并将时间间隔设置为hours
0.. 9999
hours
DATE_ADD(@start_date, INTERVAL (a.a) + (10 * b.a) + (100 * c.a) + (1000 * d.a) HOUR)
要得到:
@start_date + 1 hour @start_date + 2 hours @start_date + 3 hours ... @start_date + 9999 hours
其他说明
所有联合创建一个派生表。该代码等效于您创建具有1000行的表并从中进行选择。
SELECT * FROM table1000 1000 rows return
然后,您可以使用该表上的每个值和常量@start_date来更改每一行
@start_date
现在您有了一个列表,其中包含1000天的起始日期 @start_date
最后,您使用@end_date进行过滤,以删除大于所需日期的日期。
@end_date