How do I populate empty dates in SQL results, either on the MySQL or Perl side, and what's the most straightforward way?
P粉448346289
2023-08-24 13:14:12
<p>I'm building a quick csv from a mysql table using a query like: </p>
<pre class="brush:php;toolbar:false;">select DATE(date),count(date) from table group by DATE(date) order by date asc;</pre>
<p>Then dump them directly into a file in perl: </p>
<pre class="brush:php;toolbar:false;">while(my($date,$sum) = $sth->fetchrow) {
print CSV "$date,$sumn"
}</pre>
<p>However, there are date gaps in the data: </p>
<pre class="brush:php;toolbar:false;">| 2008-08-05 | 4 |
| 2008-08-07 | 23 |</pre>
<p>I want to pad the data, filling in missing dates with zero-count entries, and end up with: </p>
<pre class="brush:php;toolbar:false;">| 2008-08-05 | 4 |
| 2008-08-06 | 0 |
| 2008-08-07 | 23 |</pre>
<p>I cobbled together a very clumsy (almost certainly buggy) workaround using an array of days in the month and some math, but there's definitely a more direct way, either in mysql or perl. </p>
<p>Any genius ideas/suggestions on why I’m so stupid? </p>
<hr />
<p>In the end I chose to use a stored procedure to generate a temporary table to handle the required date range for several reasons: </p>
<ul>
<li>I know the date range to look for every time</li>
<li>Unfortunately, this server cannot currently install perl modules, and it is in such bad shape that it does not have anything like Date::-y installed</li>
</ul>
<p>The date/time iteration in perl answer is also very good, I wish I could select multiple answers! </p>
When I needed to deal with this problem, to fill in the missing dates, I actually created a reference table containing just all the dates I was interested in and joined the data tables on the date fields. It's crude and crude, but it works.
As for the output, I would use SELECT INTO OUTFILE instead of manually generating the CSV. This way we don't have to worry about escaping special characters.
When you need something similar on the server side, you usually create a table containing all possible dates between two points in time, and then do a left join to this table with the query results. Something similar to the following:
In this specific case, it would be better to do some check on the client side and add some additional string if the current date is not the day after the previous day.