MySQL 生成一系列日期

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14105018/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 16:00:04  来源:igfitidea点击:

Generating a series of dates

mysql

提问by Bohemian

What is the best way in mysql to generate a series of dates in a given range?

mysql 在给定范围内生成一系列日期的最佳方法是什么?

The application I have in mind is to write a report query that returns a row for every date, regardless of whether there is any data to report. In its simplest form:

我想到的应用程序是编写一个报告查询,该查询为每个日期返回一行,而不管是否有任何数据要报告。以其最简单的形式:

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

I have tried creating a table with lots of dates, but that seems like a poor workaround.

我曾尝试创建一个包含很多日期的表格,但这似乎是一个糟糕的解决方法。

采纳答案by BellevueBob

I think having a calendar tableis a good idea; you can gain a lot of reporting and query functionality, especially when filling sparse data ranges.

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

I found this articlewith what seems to be a good example.

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

回答by computingfreak

if you're in a situation like me where creating temporary tables is prohibited, and setting variables is also not allowed, but you want to generate a list of dates in a specific period, say current year to do some aggregation, use this

如果你像我这样的情况禁止创建临时表也不允许设置变量,但你想生成一个特定时期的日期列表,比如当年做一些聚合,使用这个

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'

回答by bonCodigo

You may use a variable generate date series:

您可以使用变量生成日期系列:

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) 
;

Not sure if this is what you have tried :) though.

不确定这是否是您尝试过的:) 不过。

Next use above generated query as a table to left join:

接下来使用上面生成的查询作为表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
;

回答by Saharsh Shah

You can also use Temporary Table to generate date series. Check below query:

您还可以使用临时表来生成日期系列。检查以下查询:

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;