MySQL:按小时分组,需要显示所有小时,null表示没有数据

时间:2015-06-08 14:23:48

标签: mysql sql query-optimization

以下是查询:

SELECT h.idhour, h.`hour`, outnumber, count(*) as `count`, sum(talktime) as `duration` 
FROM (
     SELECT 
        `cdrs`.`dcustomer` AS `dcustomer`,
        (CASE
            WHEN (`cdrs`.`cnumber` like "02%") THEN '02'
            WHEN (`cdrs`.`cnumber` like "05%") THEN '05'
        END) AS `outnumber`,
        FROM_UNIXTIME(`cdrs`.`start`) AS `start`,
         (`cdrs`.`end` - `cdrs`.`start`) AS `duration`,
         `cdrs`.`talktime` AS `talktime`
    FROM `cdrs`
    WHERE `cdrs`.`start` >= @_START and `cdrs`.`start` < @_END
    AND `cdrs`.`dtype` = _LATIN1'external'
    GROUP BY callid
   ) cdr 

   JOIN customers c ON c.id = cdr.dcustomer
   LEFT JOIN hub.hours h ON HOUR(cdr.`start`) = h.idhour

    WHERE (c.parent = _ID or cdr.dcustomer = _ID or c.parent IN 
        (SELECT id FROM customers WHERE parent = _ID))

   GROUP BY h.idhour, cdr.outnumber
   ORDER BY h.idhour;

上述查询结果会跳过没有数据的小时数,但我需要显示所有小时数(00:00到23:00),其中包含null或0值。我怎么能这样做?

2 个答案:

答案 0 :(得分:0)

SELECT h.idhour
, h.hour
,IFNULL(outnumber,'') AS outnumber
,IFNULL(cdr2.duration,0) AS duration
,IFNULL(output_count,0) AS output_count
FROM hub.hours h
  LEFT JOIN ( 
 SELECT HOUR(start) AS start,outnumber, SUM(talktime) as duration ,COUNT(1) AS output_count
 FROM
 (
 SELECT cdrs.dcustomer AS dcustomer
 , (CASE WHEN (cdrs.cnumber like "02%") THEN '02' WHEN (cdrs.cnumber like "05%") THEN '05' END) AS outnumber
 , FROM_UNIXTIME(cdrs.start) AS start
 , (cdrs.end - cdrs.start) AS duration
 , cdrs.talktime AS talktime 
 FROM cdrs cdrs
 INNER JOIN customers c ON c.id = cdrs.dcustomer 
 WHERE cdrs.start >= @_START and cdrs.start < @_END AND cdrs.dtype = _LATIN1'external' 
 AND
 (c.parent = _ID or cdrs.dcustomer = _ID or c.parent IN (SELECT id FROM customers WHERE parent = _ID))
 GROUP BY callid 
 ) cdr 
 GROUP BY HOUR(start),outnumber
 ) cdr2 
 ON cdr2.start = h.idhour
 ORDER BY h.idhour

答案 1 :(得分:0)

你需要一张包含所有时间的桌子,没有别的。

然后将LEFT JOIN与“左”的小时表和“右”的当前查询一起使用:

SELECT b.*
    FROM hours h
    LEFT JOIN ( ... ) b ON b.hr = h.hr
    WHERE h.hr BETWEEN ... AND ...
    ORDER BY hr; 

b.*中的任何缺失小时都将为NULL。