Mysql日期分組無數據查詢填充0


前言

這篇文章標題不好取。。。(主要是生成連續的日期),本文關鍵點有:Mysql 獲取指定時間段內的所有日期列表,
Mysql 按照日期分組查詢沒有數據的日期也一並查詢出來。

本文原文鏈接地址:http://nullpointer.pw/Mysql%E6%97%A5%E6%9C%9F%E5%88%86%E7%BB%84%E6%97%A0%E6%95%B0%E6%8D%AE%E6%9F%A5%E8%AF%A2%E5%A1%AB%E5%85%850.html

問題

產品提出一個需求,需要展示這樣的一張折線圖,用來反映指定時間段內網站注冊用戶的增加趨勢,於是需要后端的 JSON 工程師給出對應的接口。

疏忽大意

具體的表結構和數據是這樣的

JSON 工程師不加思索,展開了 CRUD 大法,順手寫下了一個 SQL,不到5分鍾,接口完活,測都沒測試直接給到了前端開發。

select date(t.create_time) as `date`,
       count(t.id)  as num
from t_user t
group by `date`;

前端拿到數據后開始繪圖,結果畫的圖完全不對啊,因為時間不是連續的。於是反饋到了 JSON 工程師這里。

JSON 工程師一想,哎喲,沒考慮掉某天沒有數據的情況,分組查詢的話,肯定缺少這一天的數據的。

+------------+-----+
|    date    | num |
+------------+-----+
| 2019-05-06 |  2  |
+------------+-----+
| 2019-05-08 |  2  |
+------------+-----+
| 2019-05-09 |  9  |
+------------+-----+

正確的做法應該是即使某天沒有數據,也填充一個 0 作為記錄值。

修正查詢數據

找到了問題就好辦了,捋了一下邏輯分成了兩步

一、拿到所有日期

2019年09月12日更新

感謝評論區中 @一個小可愛(感覺是個有趣的人哈哈)提出的方法,於是我就來更新一下本文了。最好的方式是在 Java 代碼中處理生成連續的日期,然后創建一個 map 對象,初始化所有的鍵值對的值為 0,然后遍歷查詢出來的按照日期作為 key,之后進行 put 覆蓋默認值即可。

提供一個生成連續日期的方法

public static Set<String> getBetweenDate(String start, String end) {
  LocalDate startDate = LocalDate.parse(start);
  LocalDate endDate = LocalDate.parse(end);
  long between = ChronoUnit.DAYS.between(startDate, endDate);
  if (between < 1) {
    return Stream.of(start, end).collect(Collectors.toSet());
  }

  return Stream.iterate(startDate, e -> e.plusDays(1))
    .limit(between + 1)
    .map(LocalDate::toString)
    .collect(Collectors.toSet());
}


public static void main(String[] args) {
  Set<String> days = BaseTest.getBetweenDate("2019-08-29", "2019-09-02");
  log.info("{}", days);
}

二、按照日期分組查詢

原來的文章可能會造成誤解,已更新掉
按照日期分組查詢,遍歷查詢結果,覆蓋第一步里的時間map的值即可。

結果如下:

+------------+-----+
|    date    | num |
+------------+-----+
| 2019-05-03 |  0  |
+------------+-----+
| 2019-05-04 |  0  |
+------------+-----+
| 2019-05-05 |  0  |
+------------+-----+
| 2019-05-06 |  2  |
+------------+-----+
| 2019-05-07 |  0  |
+------------+-----+
| 2019-05-08 |  2  |
+------------+-----+
| 2019-05-09 |  9  |
+------------+-----+

順利達到了目的,收工!

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM