在實際項目中,不免有數據分析模塊,例如按時間分組,需要統計每天的數量,作爲後端,可以在邏輯層進行處理,便利一邊結果集,沒有補0,也可以在數據層,查出來之後,直接就是想要的結果。下面介紹在數據層,直接獲取已經處理好的數據。
這裏利用存儲過程,往臨時表裏插入指定日期範圍的所有日期。
臨時表結構如下:
CREATE TABLE `calendar` (
`date` date NOT NULL,
UNIQUE KEY `unique_date` (`date`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
存儲過程如下
DELIMITER $$
DROP PROCEDURE IF EXISTS `create_calendar`$$
CREATE DEFINER=`root`@`%` PROCEDURE `create_calendar`(s_date DATE, e_date DATE)
BEGIN
SET @truncateSql = 'truncate table calendar';
PREPARE tsql FROM @truncateSql;
EXECUTE tsql;
WHILE s_date <= e_date DO
INSERT IGNORE INTO calendar VALUES (DATE(s_date)) ;
SET s_date = s_date + INTERVAL 1 DAY ;
END WHILE ;
END$$
DELIMITER ;
執行存儲過程
CALL create_calendar('2019-09-01','2019-09-30')
結果如下
在業務層,先在業務表中進行統計查詢,如下
SELECT DATE_FORMAT(t.`time`, '%Y-%m-%d') tdate, COUNT(*) num
FROM tb_smoke_sensor_warn t
WHERE DATE_FORMAT(t.time,'%Y-%m-%d') >= '2019-09-01'
AND DATE_FORMAT(t.time,'%Y-%m-%d') <= '2019-09-30'
GROUP BY DATE_FORMAT(t.`time`, '%Y-%m-%d')
查詢結果如下
將執行存儲過程的臨時表左連接統計查詢的數據,就可以補齊不存在日期的數量
SELECT
c.date,
IFNULL(temp.num, 0) num
FROM
calendar c
LEFT JOIN
(SELECT
DATE_FORMAT(t.`time`, '%Y-%m-%d') tdate,
COUNT(*) num
FROM
tb_smoke_sensor_warn t
WHERE DATE_FORMAT(t.time, '%Y-%m-%d') >= '2019-09-01'
AND DATE_FORMAT(t.time, '%Y-%m-%d') <= '2019-09-30'
GROUP BY DATE_FORMAT(t.`time`, '%Y-%m-%d')) temp
ON c.date = temp.tdate
ORDER BY DATE ASC
結果如下: