【实用】Mysql 按照时间(年月周日)维度统计,不存在时间数据 自动补充 0 数值

这篇具有很好参考价值的文章主要介绍了【实用】Mysql 按照时间(年月周日)维度统计,不存在时间数据 自动补充 0 数值。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言


ps: 网上看了一大堆文章, 介绍的东西真的是很够呛, 就没一个能真正用起来的, 各个都是自动补,然后很多都是不好用的。

我自己整理一篇,这是真能用。

本篇内容 :

① 按照 日 、周、月 、年  的维度 去对数据 做分组统计 

② 不存在的数据自动补充 0  (实用)

正文

不多说,开搞。


结合实例 :

先看我们的表 student 

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

 建表sql:

CREATE TABLE `student` (
    `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
    `name` VARCHAR(50) NULL DEFAULT NULL COMMENT '名字' COLLATE 'utf8_general_ci',
    `admission_time` DATETIME NULL DEFAULT NULL COMMENT '入学时间',
    PRIMARY KEY (`id`) USING BTREE
)


现在我们就举个简单的业务场景:

根据admission_time 入学时间,按照年月日周这些维度 去统计 学生数量。


我们来做一些模拟数据,8条数据:

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

第一部分 , 按照时间维度统计的SQL 写法


我们先简单看看 按照 日 、周  、月 、年 的统计 sql怎么写 :


日 维度 

sql:

SELECT date_format(admission_time, '%Y-%m-%d') date_time, COUNT(*) num
FROM student
GROUP BY date_time ;

 看看效果:


sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

 
ps : 注意了 这些 ‘-’ 是我们定义的格式, 我们不要 ‘-’ 换成其他的也是可以的,但是 不能不要 ymd 这些关键字。

举个小栗子:
 
 
比如 ,date_format(admission_time, '收藏%Y点%m赞%d')

SELECT date_format(admission_time, '收藏%Y点%m赞%d') date_time, COUNT(*) num
FROM student
GROUP BY date_time ;

看看效果 :

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

周维度 

 sql:

SELECT DATE_FORMAT(admission_time,'%Y-%u 周')  AS  date_time, COUNT(*) num FROM student GROUP BY date_time;

ps : 为了让你们知道 这个周的概念, 我故意加了个中文。 而且特意把一条数据 时间改成 22年的最后一周的一天。

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

 
看看效果 :

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计


月维度 

sql:

SELECT DATE_FORMAT(admission_time, '%Y-%m') date_time, COUNT(*) num
FROM student
GROUP BY date_time ;

看看效果 :

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

年维度

sql:

SELECT DATE_FORMAT(admission_time, '%Y') date_time, COUNT(*) num
FROM student
GROUP BY date_time ;

看看效果:

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

好了 知道这些基础的 时间分组sql 用法之后, 那么我们接下来就 来 玩下怎么 解决自动补 0 的这个问题。


第二部分 , 自动填充不存在的数据 数值 0


首先,如果说 sql查出来的数据没有, 我们拿月维度的来 做个示例 ,就像这样 :

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计 

这里突然想到个点,很多人说那这里面混了 2022年, 2023年的数据, 我想要指定查询某段时间的怎么搞?

其实一样的,就根据时间查询就行:

比如像这样传入我们的筛选时间范围,按照月就这样 :

sql:


SELECT * FROM (

select date_format(admission_time, '%Y-%m') date_time, count(*) num
from student
group by date_format(admission_time, '%Y-%m')

)t WHERE t.date_time BETWEEN '2023-01' AND   '2023-03'

效果:


sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

 
回到刚才,可以看到统计出来的数据, 比如说23年的,有1月的,2月的, 3月的, 那么 4,5,6,7后面这些月份,没数据,那怎么办?

如何默认去填充 0呢 ?
 

写代码填充,后端拿到查数据库返回的数据,for循环遍历,检测时间段内的日期, 比如说 12个月,看看哪个月没有,就填充。

确实 这是可以的, 但是今天这一篇介绍的是通过sql返回 , 不考虑代码上面的填补。

接下来看看SQL怎么玩 。

思路&想法 : 
 

我们能查出来 student 现有的日期数据, 那么缺少的数据 我也得给整出来 。

那我们肯定不能去改 student表的数据呀, 现在就是单纯少了一些 空白月份的数据 。


所以我们选择 临时数据表的思维。


ps : 网上一大堆文章,都让咱们去跑个存储过程  强行生成一个表..

你看看(一万个拒绝) 

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

 还有这种,按照目前时间拼接出来的:

(5000个拒绝,这种now 直接切割到现在,还得写一大堆这种01,02,03,04;
   如果我是要填充 日维度的数据,那我这sql代码量不就爆炸了?

) 
sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

 这种也是:
sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

OK, 我们来看看我们的SQL :

 

select DATE_FORMAT(date_add('2023-01-01', interval row MONTH),'%Y-%m') date_time from
 ( 
    SELECT @row := @row + 1 as row FROM 
    (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t,
    (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t2, 
    (SELECT @row:=-1) r
 ) se
 where DATE_FORMAT(date_add('2023-01-01', interval row MONTH),'%Y-%m') <= DATE_FORMAT('2023-12-01','%Y-%m')

效果 :
 

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

ps: 这里用了月举例, 要弄年或周或者日的 在文末有补充。

sql 作用简析 :

简析点一 


sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计
 

 简析点二

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

 可以看到 ,这里面 我写了2行这个玩意  。

(select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t
 

简单说下:
 

写一行这个玩意, 代表能搞出 10 条 符合 范围时间内日期格式时间数据 ;

当写多一行呢(2行的时候),代表 10 * 10 =100 条 

当再写多一行呢(3行的时候)?  10*10*10 =1000条

所以我们上面的sql,我写了2行,

代表 在我传入的时间范围 2023-01-01 到 2323-12-01  内

我写的时间格式是取月, 一共其实就12 个月数据,也就是12条, 但是只写一次10条不够用,我也就用了2次(100条)。

言下之意, 其实你跟我这样写2次,100条, 什么概念, 1年12个月 相当于12条,这样 100条相当于可以查跨度 8年的时间了 (8*12-96)

如果你不是要查日, 业务需求一般不会让咱们写跨度这么大的。

当然了,如果就是有, 那么我们大不了直接写 4条, 相当于 10*10*10*10 =1 万  条。

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

OK,不啰嗦,回到我们的示例 :

我们现在 如果说是查跨度 2年的数据, 比如现在按照我们part的sql 查出来是这样子的 。

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

可以看到结果集, 22年数据 缺了很多 需要补0的, 23年也缺了很多。

所以我们这时候需要做一个 left join 即可解决自动补 0 的事情。

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

sql操作图析:
 

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

sql:


SELECT  A.date_time, COALESCE(B.num, 0) as num  FROM 


(

SELECT DATE_FORMAT(date_add('2023-01-01', interval row MONTH),'%Y-%m') date_time FROM
 ( 
    SELECT @row := @row + 1 as row FROM 
    (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t,
    (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t2,
	 (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t3,
	 (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t4,
	  
    (SELECT @row:=-1) r
 ) se
WHERE DATE_FORMAT(date_add('2023-01-01', interval row MONTH),'%Y-%m') <= DATE_FORMAT('2023-12-01','%Y-%m')

) A


LEFT JOIN 

(

SELECT DATE_FORMAT(admission_time, '%Y-%m') date_time, COUNT(*) num
FROM student
GROUP BY DATE_FORMAT(admission_time, '%Y-%m')

) B


ON    A.date_time= B.date_time

看看效果 :

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

这盛世如我所愿, 好了, 该篇就到这。 

文末补充 日、年、周 维度的 列出完整数据条sql :

按日 列出范围内日期的sql :
 

select date_add('2023-01-01', interval row DAY) date from
 ( 
    SELECT @row := @row + 1 as row FROM 
    (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t,
    (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t2,
	  (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t3,
	   (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t4,   
    (SELECT @row:=-1) r
 ) se
 where date_add('2023-01-01', interval row DAY) <= '2023-01-20'

 效果:

sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计

按周 列出范围内日期的sql :

按照周要注意一点,当传入每年的01-01这一天的时候 会出现0周 ,可以做一下处理。

 select DATE_FORMAT(date_add('2023-01-01', interval row WEEK),'%Y-%u') date_time from
 ( 
    SELECT @row := @row + 1 as row FROM 
    (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t,
    (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t2,
	 (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t3,
	 (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t4,
	  
    (SELECT @row:=-1) r
 ) se
 where DATE_FORMAT(date_add('2023-01-01', interval row WEEK),'%Y-%u') <= DATE_FORMAT('2023-01-06','%Y-%u')

按年 列出范围内日期的sql :


select DATE_FORMAT(date_add('2020-01-01', interval row YEAR),'%Y') date_time from
 ( 
    SELECT @row := @row + 1 as row FROM 
    (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t,
    (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t2,
	 (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t3,
	 (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t4,
	  
    (SELECT @row:=-1) r
 ) se
 where DATE_FORMAT(date_add('2020-01-01', interval row YEAR),'%Y') <= DATE_FORMAT('2023-12-01','%Y')
 

效果:
sql按照年月日分组 并将没有的日期补齐 数值填0,MySQL,mysql,数据库,补0,日期分组,统计文章来源地址https://www.toymoban.com/news/detail-775072.html

到了这里,关于【实用】Mysql 按照时间(年月周日)维度统计,不存在时间数据 自动补充 0 数值的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MySQL场景分析--按照班级查询,并统计各班级男、女的人数和总人数

    现在有一张学生表,字段如下。请按照班级查询,并统计各班级男、女的人数和总人数。 Group by SQL GROUP BY 子句用来根据指定的字段对结果集(选取的数据)进行分组,如果某些记录的指定字段具有相同的值,那么它们将被合并为一条数据。 通俗地理解,GROUP BY 子句将根据指

    2024年02月05日
    浏览(62)
  • Java获取指定时间一周至周日的日期

     Java获取指定时间一周至周日的日期: 测试类: 输出:  

    2024年02月13日
    浏览(47)
  • MySQL时间分组:按小时统计数据(mysql按小时分组)

    MySQL时间分组是一类涉及MySQL数据库的SQL语句,能够以小时对数据进行分组统计。 比如,如果你想根据一定的时间间隔,把MySQL数据库中的记录分成几组,那么MySQL时间分组技术就派上用场了。 MySQL时间分组主要使用MySQL语句YEAR(), WEEK(), HOUR()和GROUP BY来实现,按小时统计数据实

    2024年02月12日
    浏览(54)
  • mysql统计近7天数据量,,按时间戳分组

    可以使用以下 SQL 语句来统计近7天的数据量,并按时间戳分组。如果某一天没有数据,则将其填充为0。 解释说明: DATE_FORMAT(FROM_UNIXTIME( timestamp ), \\\'%Y-%m-%d\\\') AS date 将时间戳转换为日期格式,例如 2021-03-01。 COUNT(*) AS count 统计每天数据的数量。 WHERE timestamp = UNIX_TIMESTAMP(DATE_SUB

    2024年02月13日
    浏览(58)
  • mysql 近一年、近一月、昨日、近一周等时间统计

    在此基础上,有部分业务场景需要符合一些统计图形进行展示: 一、统计近一年每个月的数据 二、统计近一月30天的数据 ps:course_date表可以试任意一个表,但是前提表的数据量必须大于查询的天数跨度 三、当天按照小时展示 仅用于自己学习参考,如有错误,可提醒修改。

    2024年02月11日
    浏览(34)
  • elementUI moment 年月日转时间戳 时间限制

       

    2024年02月11日
    浏览(60)
  • 获取两个时间段之间的年月

     //获取两个时间段之间的年月         getMonthBetween(start,end){               var result = [];               var s = start.split(\\\"-\\\");               var e = end.split(\\\"-\\\");               var min = new Date();               var max = new Date();               min.setFullYear(s[0],s[1]);          

    2024年03月21日
    浏览(61)
  • 如何将时间戳转化为年月日时分秒格式

    首先获取到当前的时间戳或者需要转化为时间的时间戳 然后使用getFullYear、getMonth、 getDate、getHours、getMinutes、getSeconds等方法来获取当前时间的年月日时分秒 最后使用字符串拼接的方式得到我们想要的时间 如果往后端传时间有严格要求必须是0000-00-00 00:00:00这种格式再做处理

    2024年02月15日
    浏览(54)
  • SQL Server ,日期时间函数将时间日期类型的值截取为年月日

    使用 CONVERT 函数将日期时间类型的值转换为字符串类型,同时指定格式为 yyyyMMdd(例如2022年6月30日的日期字符串为\\\'20220630\\\')。 sql复制代码 在上述例子中,我们使用 GETDATE 函数获取当前的日期时间,然后使用 CONVERT 函数将其转换为格式为 yyyyMMdd 的字符串类型。 如果要将日期

    2024年02月16日
    浏览(45)
  • javascript设置指定年月日,js动态显示当前时间

    大家好,本文将围绕js中如何动态显示日期时间展开说明,javascript设置指定年月日是一个很多人都想弄明白的事情,想搞清楚js动态显示当前时间需要先了解以下几个事情。 创建showTime()函数,利用JavaScript中的Date对象的属性及方法获取时间,利用Window对象的 setInterval() 方法按

    2024年02月03日
    浏览(146)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包