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  |
+------------+-----+

顺利达到了目的,收工!

参考

  • https://www.cnblogs.com/zhengguangpan/p/10308886.html
  • https://blog.csdn.net/Dai_Aixy/article/details/83144619
  • https://www.cnblogs.com/dennyzhangdd/p/8073181.html

原文地址:https://www.cnblogs.com/vcmq/p/12149646.html

时间: 2024-10-08 00:36:53

Mysql日期分组无数据查询填充0的相关文章

联合分组、子查询、视图、事务、python操作mysql、索引

目录 联合分组.子查询.视图.事务.python操作mysql.索引 一.联合分组 二.子查询 三.all 与any:区间修饰条件 四.视图:view 视图的增删改 五.事务 5.1.事务的概念 5.2.事务的四大特性 六.pymysql 模块:python操作mysql 6.1 安装pymysql 模块 6.2 python用pymysql 操作mysql步骤 6.3 游标操作 6.4 pymysql事务 6.5 sql注入 七.索引 联合分组.子查询.视图.事务.python操作mysql.

Day2 MySql函数以及单表查询

SQL中的运算符 算术运算符 --算术运算符(子句) select 1+1; select 2-1; select 2*2; select 3/4; --0.75 select 3/0; --NULL select 3 div 4; --0 比较运算符> < >= <= != = --0表示false,1表示true select 1=1; --1 select 1!=1; --0 逻辑运算符  and or ! select 1=1 and 1!=1; 位运算符 | ^ &

mysql四-1:单表查询

阅读目录 一 单表查询的语法 二 关键字的执行优先级(重点) 三 简单查询 四 WHERE约束 五 分组查询:GROUP BY 六 HAVING过滤 七 查询排序:ORDER BY 八 限制查询的记录数:LIMIT 九 使用正则表达式查询 一 单表查询的语法 SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数 二 关键字的执行优先级(重点) 重点中的重点:关键字的执行优先级 f

Mysql(四)-1:单表查询

一 单表查询的语法 SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数 二 关键字的执行优先级(重点) 重点中的重点:关键字的执行优先级 from where group by having select distinct order by limit 1.找到表:from 2.拿着where指定的约束条件,去文件/表中取出一条条记录 3.将取出的一条条记录进行分组group

MySQL学习9 - 单表查询

一.单表查询的语法 二.关键字的执行优先级(重点) 三.单表查询示例 1.where约束 2.group by分组查询 3.聚合函数 4.HAVING过滤 5.order by查询排序 6.limit 限制查询的记录数 一.单表查询的语法 SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数 二.关键字的执行优先级(重点) 重点中的重点:关键字的执行优先级 from where

mysql 日期类型比较

MySQL 日期类型:日期格式.所占存储空间.日期范围 比较. 日期类型        存储空间       日期格式                 日期范围 ------------ ---------   --------------------- ----------------------------------------- datetime       8 bytes   YYYY-MM-DD HH:MM:SS   1000-01-01 00:00:00 ~ 9999-12-31

Mysql 日期类型比较 TIMESTAMPDIFF

在数据库查询中,经常遇到计算2个日期相差值,SQL提供一个非常有用的函数:TIMESTAMPDIFFT. 基本语法:TIMESTAMPDIFF(interval,datetime_expr1,datetime_expr2) 其中,interval的取值可以为:SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER or YEAR 如:查询2个日期相差的天数 SELECT TIMESTAMPDIFF(DAY,"2015-12-10",NOW())

MySQL基础学习之数据查询

一般查询 SELECT * FROM 表名 SELECT 属性名  FROM  表名 条件查询 SELECT 属性名 FROM 表名  WHERE 条件表达式 查询数据值1,数据值2的表单 SELECT *  FROM  表名  WHERE  属性名 [NOT] IN(数据值1,数据值2....) 查询数值1,数据2的表单 SELECT *  FROM  表名  WHERE  属性=值  AND 属性1=值1 查询数值1到数值2之间的表单 SELECT *  FROM  表名  WHERE  属

MySQL:MySQL日期数据类型、MySQL时间类型使用总结

MySQL 日期类型:日期格式.所占存储空间.日期范围 比较. 日期类型        存储空间      日期格式                日期范围------------  ---------  --------------------- -----------------------------------------datetime      8 bytes  YYYY-MM-DD HH:MM:SS  1000-01-01 00:00:00 ~ 9999-12-31 23:59:5