2014-04-11 41 views
0

所以基本上我需要在經過48個小時的小時基礎上產生一個報告。 對於任何空時我想返回0爲total_videostime_in_seconds按小時計算包括空時在內的行數?

但我的嘗試似乎並沒有被返回空行,而不是我得到:

period     total_videos time_in_seconds 
Apr 10th 14 00:00-00:59 11   406.00   
Apr 10th 14 02:00-02:59 5    70.00    
Apr 10th 14 03:00-03:59 10   110.00   
Apr 10th 14 06:00-06:59 1    85.40    
Apr 10th 14 07:00-07:59 4    103.00   
Apr 10th 14 08:00-08:59 5    292.44   
Apr 10th 14 12:00-12:59 1    2258.52   
Apr 10th 14 21:00-21:59 5    5189.33   
Apr 10th 14 22:00-22:59 1    182.39   
Apr 10th 14 23:00-23:59 9    119.16   
Apr 11th 14 03:00-03:59 1    2039.13 

下面是該查詢。

#Create a table of all 24 hours 
DROP TABLE IF EXISTS hours; 
CREATE TEMPORARY TABLE hours (`hour` INT); 
INSERT INTO hours (`hour`) VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23); 

#Create a table that contains todays date, yesterdays date, and the day before (48 hours) 
DROP TABLE IF EXISTS dates; 
CREATE TEMPORARY TABLE dates (`date` DATE); 
INSERT INTO dates(`date`) VALUES (DATE(NOW())), (DATE(NOW() - INTERVAL 24 HOUR)), (DATE(NOW() - INTERVAL 48 HOUR)); 

SELECT 
DATE_FORMAT(v.`created_at`,'%b %D %y %H:00-%H:59') AS period, 
COUNT(v.created_at) AS `total_videos`, 
SUM(v.duration) AS `time_in_seconds` 
FROM videos AS v 
RIGHT OUTER JOIN hours AS h ON HOUR(v.`created_at`) = h.hour 
RIGHT OUTER JOIN dates AS d ON DATE(v.`created_at`) = d.date 
    WHERE v.created_at IS NULL OR DATE(v.created_at) >= (SYSDATE() - INTERVAL 48 HOUR) 
GROUP BY d.date, h.hour 
ORDER BY d.date, h.hour ASC; 
+0

您不需要創建臨時表,最好使用sys.objects或類似的select row_number()來生成一些東西。我會首先考慮做一個更簡單的查詢,因爲問題看起來是在外連接 - 可能是左外連接。 – kayakpim

回答

0

我承認我在您的聲明中找不到缺陷。在外部連接表(這是您的案例中的視頻)出現在where子句中的條件很少見。當人們這樣做時,他們經常忘記那裏的外部聯合記錄。但是你沒有。你顯式檢查null,所以我沒有看到它有什麼問題。

你知道select語句將返回完全空行的差距,是嗎?結果列表中顯示的所有值均來自視頻。但是,應該顯示這些空行。奇怪。

你可能想嘗試它使用左聯接是比較常見的這種說法,因此更易於讀取,我們大多數人:

SELECT 
    d.date, 
    h.hour, 
    DATE_FORMAT(v.created_at,'%b %D %y %H:00-%H:59') AS period, 
    COUNT(v.created_at) AS total_videos, 
    SUM(v.duration) AS time_in_seconds 
FROM hours as h 
CROSS JOIN dates d 
LEFT JOIN videos AS v ON DATE(v.created_at) = d.date AND HOUR(v.created_at) = h.hour 
WHERE v.created_at IS NULL OR 
GROUP BY d.date, h.hour 
ORDER BY d.date, h.hour; 

我添加d.date和h.hour到結果測試目的列。這個聲明是否有效?