在sql结果中填充空日期的最简单方法是什么(在mysql或perl端)?

use*_*196 33 mysql perl calendar datediff

我正在从一个mysql表构建一个快速的csv,其查询如下:

select DATE(date),count(date) from table group by DATE(date) order by date asc;
Run Code Online (Sandbox Code Playgroud)

并通过以下方式将它们转储到perl中的文件:

while(my($date,$sum) = $sth->fetchrow) {
    print CSV "$date,$sum\n"
}
Run Code Online (Sandbox Code Playgroud)

但是数据中存在日期差距:

| 2008-08-05 |           4 | 
| 2008-08-07 |          23 | 
Run Code Online (Sandbox Code Playgroud)

我想填充数据以填写零计数条目的缺失日期,最终得到:

| 2008-08-05 |           4 | 
| 2008-08-06 |           0 | 
| 2008-08-07 |          23 | 
Run Code Online (Sandbox Code Playgroud)

我把一个非常笨拙(几乎肯定是错误的)的解决方法打包在一起,每个月都有一些日数和一些数学,但是在mysql或perl方面必须有更直接的东西.

面对为什么我这么愚蠢的任何天才想法/拍打?


我最终使用了一个存储过程,该过程为所讨论的日期范围生成临时表,原因如下:

  • 我知道我每次都会寻找的日期范围
  • 遗憾的是,有问题的服务器不是我可以在atm上安装perl模块的,并且它的状态已经破旧,它没有任何远程日期:: - y已安装

perl Date/DateTime迭代答案也非常好,我希望我能选择多个答案!

GSe*_*erg 20

当您在服务器端需要类似的东西时,通常会创建一个表,其中包含两个时间点之间的所有可能日期,然后将此表与查询结果连接起来.像这样的东西:

create procedure sp1(d1 date, d2 date)
  declare d datetime;

  create temporary table foo (d date not null);

  set d = d1
  while d <= d2 do
    insert into foo (d) values (d)
    set d = date_add(d, interval 1 day)
  end while

  select foo.d, count(date)
  from foo left join table on foo.d = table.date
  group by foo.d order by foo.d asc;

  drop temporary table foo;
end procedure
Run Code Online (Sandbox Code Playgroud)

在这种特殊情况下,最好在客户端进行一些检查,如果当前日期不是previos + 1,则添加一些附加字符串.


Aeo*_*eon 7

当我不得不处理这个问题时,为了填写缺少的日期,我实际创建了一个参考表,其中只包含我感兴趣的所有日期,并在日期字段中加入了数据表.这很粗糙,但它确实有效.

SELECT DATE(r.date),count(d.date) 
FROM dates AS r 
LEFT JOIN table AS d ON d.date = r.date 
GROUP BY DATE(r.date) 
ORDER BY r.date ASC;
Run Code Online (Sandbox Code Playgroud)

至于输出,我只是使用SELECT INTO OUTFILE而不是手动生成CSV.让我们免于担心逃避特殊角色.