2012-05-29 42 views
5

我需要這個圖表的目的。基本上我必須:有沒有辦法在MySQL結果集中生成「假」行?

  1. 按日期選擇所有發送的短信沒有時間部分,獲取與日期/計數對數組逐日;
  2. 在我的表格中沒有任何記錄的情況下添加「假」行,即將所有日期的「間隙」填入零。

一個例子的結果和相應的表(這裏的簡化)將是:

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 | 
+----------------+----------------------+ 

是否有這樣做的或者我應該做手工用PHP陣列打任何SQL命令?

+1

這背後的原因是什麼? –

+0

@ColeJohnson在某些圖表庫中,您必須指定時間戳(x軸)和值(y軸)來獲得折線圖。由於我只存儲了發送的短信,我需要填寫日期差距。 – gremo

+0

我爲此做的是在創建數組的while循環中,檢查日期是日期範圍數組中的下一個日期範圍,並根據需要插入。 – 2012-05-29 00:23:55

回答

4

您可以使用UNION語句

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 

編輯

我建議設立一個特殊的表加入反對。一個datetable的

創作查詢

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

現在填充此表要查詢的範圍內的所有日期值。您可以使用任何有效日期輕鬆加入此表。允許您彙總具有和不存在的日期。

+2

糾正我,如果我錯了,但這隻會增加一行結果集。我必須填補所有日期之間的「空白」。 – 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

相關問題