PHP:在数组中添加缺少的日期

时间:2012-06-30 23:14:00

标签: php mysql

我正在我的桌子上运行以下查询:

SELECT DISTINCT(date(dateAdded)) AS dateAdded, count(*) AS count FROM clients WHERE (dateAdded BETWEEN '2012-06-15' AND '2012-06-30') GROUP BY dateAdded ORDER BY dateAdded ASC

返回类似这样的内容:

2012-06-17 ¦ 5 
2012-06-19 ¦ 2 
2012-06-26 ¦ 3 
2012-06-30 ¦ 2

我需要能够填写日期范围内的任何缺失日期,如下所示:

2012-06-15 ¦ 0 
2012-06-16 ¦ 0 
2012-06-17 ¦ 5 <--
2012-06-18 ¦ 0 
2012-06-19 ¦ 2 <--
2012-06-20 ¦ 0 
2012-06-21 ¦ 0 
2012-06-22 ¦ 0 
2012-06-23 ¦ 0 
2012-06-24 ¦ 0 
2012-06-25 ¦ 0 
2012-06-26 ¦ 3 <--
2012-06-27 ¦ 0
2012-06-28 ¦ 0 
2012-06-29 ¦ 0 
2012-06-30 ¦ 2 <--

如果可能的话,我想使用某种PHP循环来做这件事。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:2)

我喜欢使用日期迭代器来解决这类问题:

class DateRangeIterator implements Iterator
{
      private $from;
      private $to;
      private $format;
      private $interval;

      private $current;
      private $key;

      function __construct($from, $to, $format = 'Y-m-d', $interval = '+1 days')
      {
            if (false === ($this->from = strtotime($from))) {
                  throw new Exception("Could not parse $from");
            }
            if (false === ($this->to = strtotime($to))) {
                  throw new Exception("Could not parse $to");
            }
            $this->format = $format;
            $this->interval = $interval;
      }

      function rewind()
      {
            $this->current = $this->from;
            $this->key = 0;
      }

      function valid()
      {
            return $this->current <= $this->to;
      }

      function next()
      {
            $this->current = strtotime($this->interval, $this->current);
            ++$this->key;
      }

      function key()
      {
            return $this->key;
      }

      function current()
      {
            return date($this->format, $this->current);
      }
}

使用它:

foreach (new DateRangeIterator('2012-04-01', '2012-04-30') as $date) {
    echo "$date\n";
}

您可以自定义日期应显示的格式以及应增加的时间间隔。

在您的情况下,您需要使用密钥作为数组索引来存储MySQL结果,例如

[ '2012-04-01' => 'some event', '2012-04-06' => 'some other event' ];

答案 1 :(得分:0)

您可以使用this answer中的方法创建一个包含两个提供日期之间所有日期的数组,然后使用array_merge结果覆盖所有已设置的值。

$empty_array = array_fill_keys(makeDateRange("2012-06-15","2012-06-30"), 0);
$result = array_merge($empty_array, $result);

答案 2 :(得分:0)

嗯..不确定在PHP中进行循环是最佳做法。为什么不修改查询以满足您的需求?

如果你在你的日期和你的桌子之间进行左外连接,你应该得到你需要的东西(除了你将有零而不是0,但这很容易处理。

我的SQL有点生疏,但它可能是这样的

SELECT dateAdded
FROM clients
WHERE  (dateAdded BETWEEN '2012-06-15' AND '2012-06-30') 
LEFT OUTER JOIN 
(
    SELECT DISTINCT(date(dateAdded)) AS dateAdded, count(*) AS count 
    FROM clients 
    WHERE (dateAdded BETWEEN '2012-06-15' AND '2012-06-30') 
    GROUP BY dateAdded ORDER BY dateAdded ASC
) AS mytable ON clients.dateAdded = mytable.dateAdded