2012-05-29 3 views
5

私はチャート目的でこれが必要です。基本的には、私はしなければならない:MySQLの結果セットに「偽の」行を生成する方法はありますか?

  1. 送信日時ですべてのSMSを日付で選択すると、日付/カウントのペアが日ごとに配列されます。
  2. 私のテーブルに何も記録されていない日に "偽の"行を追加すると、すべての日付 "ギャップ"がゼロで埋められます。

例の結果と対応するテーブル(ここでは単純化)は次のようになります。これを行うか、私は手動でPHPの配列と一緒に遊んでください必要がありますのための任意のSQLコマンドが

array(
    '2012-05-26 00:00:00' => 1, 
    '2012-05-27 00:00:00' => 0, // Fake added row 
    '2012-05-28 00:00:00' => 2, 
) 

+----------------+----------------------+ 
| Table SMS | id | sent_at    | 
+----------------+----------------------+ 
|   | 1 | 2012-05-26 21:58:41 | 
+----------------+----------------------+ 
|   | 2 | 2012-05-28 22:19:21 | 
+----------------+----------------------+ 
|   | 3 | 2012-05-28 02:19:21 | 
+----------------+----------------------+ 

ありますか?

+1

これにはどのような理由がありますか? –

+0

@ColeJohnsonいくつかの図書館図書館では、例えば折れ線グラフを得るためにタイムスタンプ(x軸)と値(y軸)を指定する必要があります。私は送信されたSMSだけを保管しているので、日付の隙間を埋める必要があります。 – gremo

+0

これは、配列を作成するwhileループにあり、日付範囲の配列から次の日付を確認し、必要に応じて挿入します。 –

答えて

4

あなたは

SELECT 
    sent_at, 
    Count(*) 
FROM (Select 
     id, 
     DATE(sent_at) as sent_at 
     FROM TableName 
     Group by Date(sent_at) 
     UNION ALL 
     Select 
     '0' as id, 
     DATE('2012-05-27') as sent_at) derived_table 
Group By sent_at 

UNIONステートメントを使用することができます編集

私は反対参加する特別なテーブルを作成し提案しました。今、あなたが照会された範囲内のすべての日付値で、この表を移入

CREATE TABLE DateTable (
    DateValue DateTime, 
    Year Int, 
    Month Int, 
    Day Int) 

を照会するためdatetableの

作成。任意の有効な日付で簡単にこのテーブルに参加できます。存在しない日付の集計を許可する。

+2

私が間違っている場合は私を訂正しますが、これは結果セットにただ1つの行を追加します。私はすべての日付の間に "ギャップ"を埋める必要があります。 – gremo

+1

@gremo特定の日付をすべて数えたい場合は、追加した(隙間を埋める)「偽の行」を持つ派生テーブルを使用する必要があります。ギャップを動的に埋めたい場合は、自分で日付表を作成することをお勧めします。これには、特定の期間のすべての日付が含まれます。次に、このテーブルに参加して不足している日付を取得します。 –

1

はい、私はこのすべての時間

DROP PROCEDURE IF EXISTS `Example`; 
DELIMITER $$ 

CREATE PROCEDURE `Example` (
    $StartDate DATE, 
    $EndDate DATE 
    ) 
BEGIN 

    DECLARE $curDay DATE; 
    SET $StartDate = IFNULL($StartDate,'2000-01-01'); 
    SET $curDay = $StartDate; 


    DROP TEMPORARY TABLE IF EXISTS `Day`; 
    CREATE TEMPORARY TABLE `Day`(
     `Date` DATE 
    ); 

    DaysLoop:LOOP 

     INSERT INTO 
      `Day`(`Date`) 
     SELECT 
      $curDay 
     ; 

     SET $curDay = $curDay + INTERVAL 1 DAY; 

     IF 
      $curDay >= $EndDate OR $curDay >= NOW() 
     THEN 
      LEAVE DaysLoop; 
     END IF; 

    END LOOP DaysLoop; 

    SELECT 
     D.Date, 
     COUNT(S.id) 
    FROM 
     `Day` AS D 
    LEFT JOIN 
     `SMS` AS S 
     ON D.Date = DATE(S.sent_at) 
    GROUP BY 
     D.Date 
    ORDER BY 
     D.Date 
    ; 

END $$ 

DELIMITER ; 

CALL Example('2012-01-01','2012-05-01'); 

私はスクリプトやその他もろもろを作成必ずバージョン管理を行い、使用して、レポートのストアドプロシージャをお勧めしますを行います。

+0

ああ、あなたは 'group by 'を持っている必要はなく、DAY_HOURなどでグループ化することもできます – KCD

関連する問題