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

うーん.. PHP でループを実行することがベスト プラクティスかどうかはわかりません。必要なものが得られるようにクエリを変更してみませんか?

一連の日付とテーブルの間で左外部結合を行うと、必要なものが得られるはずです (ただし、0 ではなく null になりますが、これは簡単に処理できます。

私の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 に答える
0

この回答のメソッドを使用して、指定された2つの日付の間のすべての日付の配列を作成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 に答える