MYSQL按小时计数返回0

时间:2014-05-08 00:46:20

标签: mysql coalesce isnull hour

我不知道如何实现这一点,但是如果查询为空,则看到在线ISNULL()和COALESCE()用于返回零。我不确定如何正确使用它虽然我直觉地认为我需要在子查询中然后在该子查询周围有ISNULL或COALESCE?

查询:

SELECT HOUR( dateAdded ) AS HOUR , COUNT( DISTINCT remoteAddr, xForwardedFor) AS cnt
FROM Track
WHERE accessMask =  '1iczo'
AND destination =  'lp_include.php'
AND dateAdded
BETWEEN  '2014-05-01'
AND  '2014-05-02'
GROUP BY HOUR
ORDER BY HOUR

非常感谢一些正确方向的帮助!

更新

我使用了@Barmar建议的内容,但它没有返回准确的结果。我使用了他提供的内容以及另一个类似情况的主题Group by should return 0 when grouping by hours. How to do this?。在发布这个主题之后,我实际上没有找到这个主题,:(不幸的是。这是最终的代码,似乎返回准确的结果,两个列不同,空数据返回为0.

SELECT a.hour, COALESCE(cnt, 0) AS cnt
FROM (SELECT 0 AS hour
UNION ALL
  SELECT 1
UNION ALL
  SELECT 2 .....
UNION ALL
  SELECT 23) a
LEFT JOIN
(SELECT COUNT(DISTINCT remoteAddr, xForwardedFor) AS cnt, HOUR(dateAdded) AS hour
  FROM Track
  WHERE accessMask =  '1iczo'
  AND destination =  'lp_include.php'
  AND dateAdded
  BETWEEN  '2014-05-01 00:00:00' AND '2014-05-01 23:59:59') AS totals
ON a.hour = totals.hour

小提琴,以便更好地参考:http://sqlfiddle.com/#!2/9ab660/7

再次感谢@Barmar,他真的让我朝着正确的方向努力寻求解决方案!

2 个答案:

答案 0 :(得分:1)

您必须加入包含所有小时数的表格。这必须是LEFT JOIN,以便结果包含Track表中没有匹配的小时数。

SELECT allHours.hour, IFNULL(cnt, 0) AS cnt
FROM (SELECT 0 AS hour
      UNION
      SELECT 1
      UNION
      SELECT 2
      UNION
      SELECT 3
      ...
      UNION
      SELECT 23) AS allHours
LEFT JOIN
     (SELECT HOUR(dateAdded) AS hour, COUNT(DISTINCT remoteAddr, xForwardedFor) AS cnt
      FROM Track
      WHERE accessMask =  '1iczo'
      AND destination =  'lp_include.php'
      AND dateAdded
      BETWEEN  '2014-05-01' AND '2014-05-02') AS totals
ON allHours.hour = totals.hour

答案 1 :(得分:0)

如果您假设每小时都有部分数据,则可以将条件部分移动到select

SELECT HOUR(dateAdded) AS HOUR ,
       COUNT(DISTINCT CASE WHEN accessMask =  '1iczo' AND destination =  'lp_include.php'
                      THEN CONCAT(remoteAddr, ',', xForwardedFor)
             END) AS cnt
FROM Track
WHERE dateAdded BETWEEN  '2014-05-01' AND '2014-05-02'
GROUP BY HOUR
ORDER BY HOUR;