mysql按日期分組(group by)查詢統計的時候,沒有數據補0的解決辦法
轉載自:http://blog.csdn.net/jie11447416/article/details/50887888
1、案例中的數據結構和數據如下
2、在沒有解決的時候,是這樣的
1 SELECT date(downtime) AS dday, count(*) AS num FROM re_device GROUP BY dday
得到如下結果,如果那天沒有數據,那麼就會沒有記錄
我們看到,時間不連續,沒有2016-3-05這一天的,這樣本來不是問題,但是,我拿出來的數據,還要畫出圖表呀,沒有當然不行,我們需要的是下面這個樣子的。
簡單的說就是,沒有數據,就要補充一個0.
3、下面我們講實現
我們要生成一個日歷的表,然後和原來的數據,聯合查詢,說到這裏,大家就知道很low了,但是,限於我水平有限,研究這個問題,半天,這個是我找到的比較好的一種實現方式。如果你又更好的,也請你給我說下。
執行下面的sql,直接誒生成日歷的表(calendar)
CREATE TABLE num (i int);-- 創建一個表用來儲存0-9的數字 INSERT INTO num (i) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);-- 生成0-9的數字,方便以後計算時間 CREATE TABLE if not exists calendar(datelist date); -- 生成一個存儲日期的表,datalist是字段名-- 這裏是生成並插入日期數據 INSERT INTO calendar(datelist) SELECT adddate( ( -- 這裏的起始日期,你可以換成當前日期 DATE_FORMAT("2016-1-1", ‘%Y-%m-%d‘) ), numlist.id ) AS `date` FROM ( SELECT n1.i + n10.i * 10 + n100.i * 100 + n1000.i * 1000+ n10000.i * 10000 AS id FROM num n1 CROSS JOIN num AS n10 CROSS JOIN num AS n100 CROSS JOIN num AS n1000 CROSS JOIN num AS n10000 ) AS numlist;
這裏我用了100000條記錄,算出來到2289年了,完全夠用了,到那個時候,出問題,我也管不了了。
完成之後,請刪除num的零時表
4、聯合查詢
1 SELECT 2 date(dday) ddate, 3 count(*) - 1 as num 4 FROM 5 ( 6 SELECT 7 datelist as dday 8 FROM 9 calendar 10 -- 這裏是限制返回最近30天的數據 11 where DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= date(datelist)&&date(datelist)<=CURDATE() 12 UNION ALL 13 SELECT 14 downtime 15 FROM 16 re_device 17 ) a 18 GROUP BY ddate
5、其他解決方法
當然,應該還有其他的解決方案,但是博主就沒有去寫了,有時間可以去寫一下。
我用的spring mvc,所以,也還是可以在java代碼中補充完整的,因為數據返回的是個map對象,那麼我們要遍歷這個對象,直接用calendar對象,生成日期作為key來遍歷,如果沒有數據,就put進去一個0,然後在限制一下,需要多少天的,就可以了。數據就完整了。
但是這樣也有一個問題,那就是map裏的數據順序會有問題,所以,使用的時候,也必須是生成calendar對象,然後構造出來日期作為key來遍歷。或者用Collections.sort()排序一下。
我個人覺得,還是上數據直接生成得比較好一點。
mysql按日期分組(group by)查詢統計的時候,沒有數據補0的解決辦法