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

2021-11-20 00:00:00 perl calendar mysql datediff

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

I'm building a quick csv from a mysql table with a query like:

select DATE(date),count(date) from table group by DATE(date) order by date asc;

然后将它们转储到 perl 文件中:

and just dumping them to a file in perl over a:

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

虽然数据中存在日期间隔:

There are date gaps in the data, though:

| 2008-08-05 |           4 | 
| 2008-08-07 |          23 | 

我想用零计数条目填充数据以填充缺失的天数,最后得到:

I would like to pad the data to fill in the missing days with zero-count entries to end up with:

| 2008-08-05 |           4 | 
| 2008-08-06 |           0 | 
| 2008-08-07 |          23 | 

我用每月的天数和一些数学计算了一个非常尴尬(而且几乎肯定有问题)的解决方法,但是在 mysql 或 perl 方面必须有更简单的方法.

I slapped together a really awkward (and almost certainly buggy) workaround with an array of days-per-month and some math, but there has to be something more straightforward either on the mysql or perl side.

有什么天才的想法/为什么我这么愚蠢?

Any genius ideas/slaps in the face for why me am being so dumb?

由于以下几个原因,我最终使用了一个存储过程,该过程为相关日期范围生成了一个临时表:

I ended up going with a stored procedure which generated a temp table for the date range in question for a couple of reasons:

  • 我知道每次要查找的日期范围
  • 不幸的是,有问题的服务器不是我可以在 atm 上安装 perl 模块的服务器,而且它的状态已经陈旧到没有远程安装任何东西 Date::-y

perl Date/DateTime 迭代答案也很好,我希望我可以选择多个答案!

The perl Date/DateTime-iterating answers were also very good, I wish I could select multiple answers!

推荐答案

当你在服务器端需要类似的东西时,你通常会创建一个包含两个时间点之间所有可能日期的表,然后用左加入这个表查询结果.像这样:

When you need something like that on server side, you usually create a table which contains all possible dates between two points in time, and then left join this table with query results. Something like this:

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

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

In this particular case it would be better to put a little check on the client side, if current date is not previos+1, put some addition strings.

相关文章