2014-05-08 30 views
0

我有這個查詢,它從12點到下午11點45分得到平均值並將這些值分組15分鐘。即使當時沒有條目,仍然顯示適當的時間集合

SELECT FROM_UNIXTIME(t_stamp/1000, '%m/%d/%Y %l:%i %p') as t_stamp, 
    ROUND(AVG(CASE WHEN id = '001' THEN value END),2) Value1, 
    ROUND(AVG(CASE WHEN id = '002' THEN value END),2) Value2, 
    ROUND(AVG(CASE WHEN id = '003' THEN value END),2) Value3 

FROM table1 
WHERE tagid IN ("001", "002", "003") and 

date(from_unixtime(t_stamp/1000)) BETWEEN "2014-05-01" AND "2014-05-01" 

GROUP BY DATE(from_unixtime(t_stamp/1000)), HOUR(from_unixtime(t_stamp/1000)), MINUTE(from_unixtime(t_stamp/1000)) DIV 15 

輸出看起來像這樣

t_stamp    | Value1 | Value2 | Value3 
05/01/2014 12:00 AM  | 199  | 99  | 100 
05/01/2014 12:15 AM  | 299  | 19  | 140 
05/01/2014 12:30 AM  | 399  | 59  | 106 
05/01/2014 12:45 AM  | 499  | 59  | 112 
. 
. 
. 
05/01/2014 11:00 PM  | 149  | 199  | 100 
05/01/2014 11:15 PM  | 599  | 93  | 123 
05/01/2014 11:30 PM  | 129  | 56  | 150 
05/01/2014 11:45 PM  | 109  | 60  | 134 

它工作正常,但我有時候發現是否有對應的條目,如時間12:30,而不是顯示

t_stamp    | Value1 | Value2 | Value3 
05/01/2014 12:00 AM  | 199  | 99  | 100 
05/01/2014 12:15 AM  | 299  | 19  | 140 
05/01/2014 12:30 AM  | Null | Null | Null 
05/01/2014 12:45 AM  | 499  | 59  | 112 

它會顯示這樣一組時間:

t_stamp    | Value1 | Value2 | Value3 
05/01/2014 12:00 AM  | 199  | 99  | 100 
05/01/2014 12:15 AM  | 299  | 19  | 140 
05/01/2014 12:33 AM  | 122  | 141  | 234 
05/01/2014 12:45 AM  | 499  | 59  | 112 

我想要發生的是當15分鐘組沒有時間時,它仍然會顯示適當的時間設置,然後在列值上顯示空值。輸出我想是這樣的:

t_stamp    | Value1 | Value2 | Value3 
05/01/2014 12:00 AM  | 199  | 99  | 100 
05/01/2014 12:15 AM  | 299  | 19  | 140 
05/01/2014 12:30 AM  | Null | Null | Null 
05/01/2014 12:45 AM  | 499  | 59  | 112 

我該怎麼做?

謝謝。

回答

0

你需要一個表格,它是基數的來源,作爲開始。暫時讓我們假設它存在,它叫做cardinal

然後,您需要創建一個查詢(虛擬表),該查詢將每15分鐘返回包含時間戳的行,從最早的相關時間戳開始,以最新結束。以下是如何爲您的查詢做到這一點。

SELECT '2014-05-01' + INTERVAL (cardinal.n * 15) MINUTE as t_stamp 
    FROM cardinal 
WHERE cardinal.n <= 24*4 

然後,你需要虛擬表連接到現有的查詢,如下

SELECT DATE_FORMAT(t_stamp.t_stamp, '%m/%d/%Y %l:%i %p') t_stamp, 
     ROUND(AVG(CASE WHEN id = '001' THEN value END),2) Value1, 
     ROUND(AVG(CASE WHEN id = '002' THEN value END),2) Value2, 
     ROUND(AVG(CASE WHEN id = '003' THEN value END),2) Value3 
    FROM table1 AS t 
    LEFT JOIN (
     SELECT '2014-05-01' + INTERVAL (cardinal.n * 15) MINUTE as t_stamp 
      FROM cardinal 
     WHERE cardinal.n <= 24*4 
     ) AS t_stamp 
     ON t_stamp.t_stamp = FROM_UNIXTIME(t.t_stamp/1000) 
WHERE tagid IN ("001", "002", "003") 
    AND date(from_unixtime(t_stamp/1000)) BETWEEN "2014-05-01" AND "2014-05-01" 
GROUP BY DATE(from_unixtime(t_stamp/1000)), 
      HOUR(from_unixtime(t_stamp/1000)), 
      MINUTE(from_unixtime(t_stamp/1000)) DIV 15 

注意,LEFT JOIN確保該行將從您的原始查詢NULL值獲得包括在結果組。

現在,這個神奇的cardinal桌子從哪裏來?

您可以將它生成爲兩個視圖,就像這樣。這個特定的視圖產生從0到100 000的數字,這足夠一年的時間。

CREATE OR REPLACE VIEW cardinal10 AS 
    SELECT 0 AS N UNION 
    SELECT 1 AS N UNION 
    SELECT 2 AS N UNION 
    SELECT 3 AS N UNION 
    SELECT 4 AS N UNION 
    SELECT 5 AS N UNION 
    SELECT 6 AS N UNION 
    SELECT 7 AS N UNION 
    SELECT 8 AS N UNION 
    SELECT 9 AS N; 


CREATE OR REPLACE VIEW cardinal AS 
    SELECT A.N + 10*(B.N + 10*(C.N + 10*(D.N + 10*(E.N)))) AS N 
    FROM cardinal10 A,cardinal10 B,cardinal10 C, 
     cardinal10 D,cardinal10 E; 

這是關於這個主題的一篇文章。 http://www.plumislandmedia.net/mysql/filling-missing-data-sequences-cardinal-integers/

相關問題