一文速学-玩转MySQL时间运算函数以及时间匹配操作详解+实例代码
前言
时间在数据库中经常作为时间索引,在数据入库和出库以及更新的时候都需要变化。在一些指标计算或者是提取某段时间的数据时,都会根据数据库中的时间索引数据进行操作。因此很大一部分我们操作数据都得先从时间数据下手,但是想要真正提取到我们想要的时间作为索引,还需要我们掌握许多功能函数方便我们操作,这是一个比较复杂的运用过程。
首先展示的数据库以及表格依然是原来的value_test表格:
用到的字段一般是time以及create_time,其中time是以bigint的形式存储,而create_time是以datetime时间类型数据存储。
一、时间加减
1.时间变量运算
前文也有详细描述关于interval这个关键字的用法,一般就是用于时间的运算操作: 例如减去一天时间为:
select (create_time - interval 1 day ) as times from value_test
这里不再重复演示,想要了解更多的可以去看第三篇文章。
2.date_add()
date_add顾名思义就是增加一个时间间隔的意思,基本语法:
date_add(<时间数据>,interval <数值> <时间单位> )
后面的时间单位和interval的时间单位类型是一样的,第三篇也已经提到过后缀时间单位,这里不做演示,下面将结合前三张的文章做一些较为复杂的时间取值:
选择至今开始到近七日总的时间片内的数据:
between cast(date_sub(date_format(curdate(),'%Y%m%d') , interval 7 day)
as DECIMAL)
and cast(date_sub(date_format(curdate(),'%Y%m%d') , interval 1 day)
as DECIMAL)
选择昨日的数据:
and time= cast(date_sub(date_format(curdate(),'%Y%m%d') , interval 1 day)
as DECIMAL)
看了前三篇文章应该很好理解套用这些函数的功能了,可以任意的进行时间加减运算了。
3. date_sub()
减去一个时间间隔,这里可以使用interval的众多时间单位来实现一些精密的时间运算。
select date_sub(create_time ,interval '1 10:10:10' day_second )
as times from value_test
意为减去1天1小时10分钟10秒:
也可以使用date_add()代替,只要interval数值为负数就好了。 如:
select date_add(create_time ,interval '-1 10:10:10' day_second )
as times from value_test
4.period_add()
period_add()函数的基本语法格式为:
period_add(P,N)
从add就可以看出来也是一个相加函数,P为指定的日期数,而N则为加减的时间。和date_add不同的是,period_add不需要使用interval指定日期数值,该函数根据输入的P的长度自动判断相加减的单位。当输入的为yyyymm时,N被判别为月份相加:
select PERIOD_ADD(202201,10) as times
当输入为yyyymmdd时,N被判定为天数:
select PERIOD_ADD(20220101,10) as times
用该函数的时候要注意一下,period_add并不适用于列运算,如果用于一列作运算则会报错:
select PERIOD_ADD(time,10) as times from value_test
> Incorrect arguments to period_add
5.period_diff(P1,P2)
该函数功能为返回P1-P2的时间差,P1和P2必须为yyyymm年月的形式,说实话这函数几乎没人用,挺鸡肋的。
select PERIOD_diff(202201,202202)as times
6.datediff(date1,date2)
返回两个日期之间的间隔:
select datediff('20220601','20220501') as time
但是date1和date2只能为日期yyyymmdd,不是这个格式将会输出null。
该函数不止可以和时间类型数据识别运算,还可以与其他存储时间数据的类型作用:
select datediff(time,'20220501') as time from value_test
而且只要到达了yyyymmdd这种格式就可以运算:
select datediff(create_time,'20220501') as time from value_test
7.timediff(time1,time2)
格式和上述datediff一样,没用什么特点:
select timediff(time(create_time),'01:00:00') as time from value_test
8.time_to_sec()、sec_to_time()
time_to_sec()该函数可以将时间全都转换为秒数:
select time_to_sec(time(create_time)) as time from value_test
sec_to_time()该函数可以将秒数转化为时间,和time_to_sec()反着来了,可以再叠加一次回到原函数:
select sec_to_time(time_to_sec(time(create_time))) as time from value_test
9.to_days(date),from_days(days)
to_days()输入date日期转换为天数:
select to_days(time) as time from value_test
date输入的参数也没有规定必须要时间类型数据,其他存储可识别的时间类型格式都可以。
其终止时间为:0000/00/00
from_days()则相反,将天数转换为date,这里我们也用两个嵌套得到原数据:
select from_days(to_days(time)) as time from value_test
10.time_formate
这里弥补一下上篇时间转换函数遗漏的time_format函数,用法很简单也只限制为时间time,与date_format不同的是:time_format可以将时间转换为00.00.00的形式:
select time_format(time(create_time),'%H.%i.%s') as time from value_test
二、时间格式匹配
1.get_format()
get_format()函数语法格式为:
get_format(<时间数据>,'<指定字符 'eur'|'usa'|'jis'|'iso'|'internal'>')
select GET_FORMAT(date,'usa' ) as time
这里直接以图表形式贴出:
时间类型 | 地区时间格式 | 返回结果 |
---|---|---|
date | 'usa' | '%m.%d.%Y' |
date | 'jis' | '%Y-%m-%d' |
date | 'iso' | '%Y-%m-%d' |
date | 'eur' | '%d.%m.%Y' |
date | 'internal' | %Y%m%d' |
datetime | 'usa' | '%Y-%m-%d %H.%i.%s' |
-------- | ----- | ------------------- |
datetime | 'jis' | '%Y-%m-%d %H:%i:%s' |
datetime | 'iso' | '%Y-%m-%d %H:%i:%s' |
datetime | 'eur' | '%Y-%m-%d %H.%i.%s' |
datetime | 'internal' | '%Y%m%d%H%i%s' |
-------- | ---------- | -------------- |
time | 'usa' | '%h:%i:%s %p' |
time | 'jis' | '%H:%i:%s' |
time | 'iso' | '%H:%i:%s' |
time | 'eur' | '%H.%i.%s' |
time | 'internal' | %H%i%s' |
---- | ---------- | ------- |
## 2.substr() |
基本语法格式:
substr(string string,num start,num length);
- string:为[字符串];
- start:为起始位置;
- length:为长度。
如果我们要选取当月的日期:
and substr(time,1,6) = substr( cast(date_sub(date_format(curdate(),'%Y%m%d')
, interval 1 day) as DECIMAL),1,6)
起始不能从0开始,只能从1开始。
select time from value_test
WHERE substr(time,1,6)>'202205'
and substr(time,1,6)<'202207'
这样就可以选取6月份的所有数据了。
点关注,防走丢,如有纰漏之处,请留言指教,非常感谢
以上就是本期全部内容。我是fanstuck ,有问题大家随时留言讨论 ,我们下期见。
转载自:https://juejin.cn/post/7165443569816666148