3

我在我的表上运行以下查询:

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 循环来做到这一点。任何帮助将不胜感激。

4

3 回答 3

3

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

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' ];
于 2012-07-01T03:37:41.727 回答
0

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

$empty_array = array_fill_keys(makeDateRange("2012-06-15","2012-06-30"), 0);
$result = array_merge($empty_array, $result);
于 2012-06-30T23:18:57.033 回答
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
于 2012-06-30T23:22:46.893 回答