数据库(postgresql和mysql)统计一个范围内的日期,没有当天日期的数据统计补0

postgresql和mysql统计一个范围内的日期,没有当天日期的数据统计补0

说明

在项目开发里面,有时候经常要根据时间对数据做统计返回给前端,如果只取一段范围内的时间查询,只返回数据库中查询到的到还简单,如果要把没有的日期也统计出来那么就感觉稍微麻烦了一点。

pgsql语句写法:
一般sql语句查询如下:
其中我的starttime在数据库中类型是timestamp
to_char()将日期转换为字符串
在这里插入图片描述
我这里查询的时间是2020-06-20到2020-06-30的时间段,发现只查到了三天的数据:
在这里插入图片描述
很明显这样写不是我所期望的结果,我期望的是2020-06-20到2020-06-27号的也能查出来并补0。

如果要实现我的那种期望结果,需要用到这个函数,如下:

补充

select date(t) as day
from 
generate_series('2020-06-20'::date,'2020-06-30', '1 days') as t

在这里插入图片描述
它能将你的开始日期到结束日期之间的日期都能显示出来

实现

将上面的二者结合,联表查询发现就查询到了自己期望的结果。

在实际开发中只需要将2个日期2020-06-20和2020-06-30换成对应的开始日期参数和结束日期参数,那么这个统计结果就是符合期望的结果的了。

SELECT a.time,COALESCE(b.counts,0) as counts from
(
SELECT
to_char(b,'yyyy-MM-dd') AS time
FROM
generate_series('2020-06-20'::date,'2020-06-30','1 days') AS b
GROUP by time 
ORDER BY time
) as a
LEFT JOIN
(
select to_char(starttime,'yyyy-MM-dd') AS starttime, count(starttime) AS counts 
from rnodbv2.v2_m_ctest_log_info
where to_char(starttime,'yyyy-MM-dd')>='2020-06-20' and to_char(starttime,'yyyy-MM-dd')<='2020-06-30'
GROUP BY to_char(starttime,'yyyy-MM-dd')
) as b
on a.time=b.starttime
order by a.time

结果如下:
在这里插入图片描述
mysql语句写法:
一般sql语句查询如下:
其中我的create_time在数据库中类型是datetime

– 将日期转化为字符串
DATE_FORMAT(CREATE_TIME,’%Y-%m-%d %H:%i:%s’)
– 将字符串转化为日期
STR_TO_DATE(‘2020-09-04 16:49:05’, ‘%Y-%m-%d %H:%i:%s’)
在这里插入图片描述
我这里查询的时间是2020-10-20到2020-10-30的时间段,发现只查到了二天的数据:
在这里插入图片描述
这里我使用这个语句来做一个虚拟的日期表

SELECT @cdate := DATE_ADD(@cdate,INTERVAL - 1 DAY) date
FROM (SELECT @cdate :=DATE_ADD('2020-10-29', INTERVAL + 1 DAY) FROM sys_user) t1 
WHERE @cdate>'2020-10-01'

注意:这个sql有个局限性,那就是你查的表的数据行数必须要大于你的日期天数,它才能显示你时间范围内的所有日期,因为我的sys_user表里面只有9条数据,所以它只会返回最后9天的日期,如果这个表数据有29条以上,那么就能显示1-29号的日期
在这里插入图片描述
sys_user表:
在这里插入图片描述

实现

将上面的二者结合,联表查询发现就查询到了自己期望的结果。

select a.date, ifnull(b.counts,0) as counts
from 
(select @cdate := date_add(@cdate,INTERVAL - 1 DAY) as date
from (select @cdate :=date_add('2020-10-29', INTERVAL + 1 DAY) from sys_user) t1 
where @cdate>'2020-10-01') as a
left join 
(select date_format(create_time,'%Y-%m-%d') create_time,count(create_time) as counts
from sys_user
where date(create_time)>='2020-10-01' and date(create_time)<='2020-10-29'
group by date_format(create_time,'%Y-%m-%d')
order by date_format(create_time,'%Y-%m-%d')) as b
on a.date=date(b.create_time)
order by a.date

结果如下:
在这里插入图片描述
当然前提是sys_user表的数据行数大于29条日期才能显示完全。实际开发一般情况下表数据不会像我这么少吧,我这里只是测试。我只是不想在创建一个日期表才这样处理,为什么mysql就没有pgsql那样的一个系统函数呢,给一个开始日期和结束日期就能生成一个虚表日期。

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值