按小时计算行数,包括空小时数?

时间:2014-04-11 03:51:19

标签: mysql sql date grouping interpolation

所以基本上我需要生成一个小时基数为48小时的报告。 对于任何空闲时间,我想为total_videostime_in_seconds返回0。

但是我的尝试似乎没有返回空行,而是我得到了:

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;

1 个答案:

答案 0 :(得分: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添加到结果列中以进行测试。这个陈述有用吗?