生成一系列date

在一个给定的范围内生成一系列date的mysql中最好的方法是什么?

我想到的应用程序是编写一个报表查询,返回每个date的行,无论是否有任何数据要报告。 最简单的forms是:

select dates.date, sum(sales.amount) from <series of dates between X and Y> dates left join sales on date(sales.created) = dates.date group by 1 

我试图创build一个有很多date的表,但是这似乎是一个糟糕的解决方法。

我认为有一个日历表是一个好主意, 您可以获得大量的报告和查询function,特别是在填充稀疏数据范围时。

我发现这篇文章似乎是一个很好的例子。

你可以使用一个variables生成date系列:

 Set @i:=0; SELECT DATE(DATE_ADD(X, INTERVAL @i:=@i+1 DAY) ) AS datesSeries FROM yourtable, (SELECT @i:=0) r where @i < DATEDIFF(now(), date Y) ; 

不知道这是你曾经尝试过:)但。

接下来使用上面生成的查询作为表的left join

 set @i:=0; select d.dates, sum(s.amount) as TotalAmount from( SELECT DATE(DATE_ADD(X, INTERVAL @i:=@i+1 DAY) ) AS dateSeries FROM Sales, (SELECT @i:=0) r where @i < DATEDIFF(now(), date Y) ) dates d left join Sales s on Date(s.Created) = Date(d.dateSeries) group by 1 ; 

您也可以使用临时表来生成date序列。 查询如下查询:

 CREATE TEMPORARY TABLE daterange (dte DATE); SET @counter := -1; WHILE (@counter < DATEDIFF(DATE(_todate), DATE(_fromdate))) DO INSERT daterange VALUES (DATE_ADD(_fromdate, INTERVAL @counter:=@counter + 1 DAY)); END WHILE; SELECT dates.dte, SUM(sales.amount) FROM daterange dates LEFT JOIN sales ON DATE(sales.created) = dates.date GROUP BY dates.dte; 

如果你处在像我这样的情况下禁止创build临时表 ,并且设置variables也是不允许的 ,但是你想在特定的时间段内生成一个date列表 ,比如当前要做一些聚合,使用这个

 select * from (select adddate('1970-01-01',t4*10000 + t3*1000 + t2*100 + t1*10 + t0) gen_date from (select 0 t0 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0, (select 0 t1 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1, (select 0 t2 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2, (select 0 t3 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3, (select 0 t4 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v where gen_date between '2017-01-01' and '2017-12-31'