【问题标题】:Generating a series of dates [duplicate]生成一系列日期[重复]
【发布时间】:2012-12-15 19:33:20
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: mysql


    【解决方案1】:

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

    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'
    

    【讨论】:

      【解决方案2】:

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

      我发现this article 似乎是一个很好的例子。

      【讨论】:

      • 这是个好主意。感谢文章链接。
      • @BellevueBob 网站因错误而关闭:PDOException: SQLSTATE[HY000] [2003] Can't connect to MySQL server on '127.0.0.1' (111) in lock_may_be_available() (line 167 /var/www/www.brianshowalter.com/includes/lock.inc)。
      【解决方案3】:

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

      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
      ;
      

      【讨论】:

      • @Bohemian 那是一条很快就能钓到的鱼;)我也需要一顶帽子:D
      • 你想买哪顶帽子?
      • @Bohemian Gangnam Style他在哪里? 欢迎您提出我的任何精彩问题或精彩答案 ;) blimey!哈哈哈,但是再等一年是lamer :P
      • 好的 - 你有一个,并且靠近另一个......祝你好运
      • 需要注意的是,yourtable 必须有比所需时间序列更多的记录,但最好不要太多,否则性能会受到影响。
      【解决方案4】:

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

      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;
      

      【讨论】:

      • 由于这个问题是 MySQL 标记的,这不是 MySQL 有效代码,这是 SQL Server (MSSQL)
      猜你喜欢
      • 1970-01-01
      • 2016-04-02
      • 2021-12-19
      • 2011-05-27
      • 1970-01-01
      • 2019-04-13
      • 2014-01-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多