注:本文仅仅是我工作用常用到sql,只是冰山一角,后续会持续更新,逐渐补全,先总结出来一起学习共同进步
热门SQL
处理时间的函数
先了解几个常用的获取当前时间的函数输出
select curdate();
select CURRENT_DATE();
select CURRENT_TIME();
select CURRENT_TIMESTAMP();
select NOW();
select sysdate();
SELECT DATE(SYSDATE());
select now(), sleep(3), now();
select sysdate(), sleep(3), sysdate();
select current_timestamp,sleep(3), current_timestamp();
select utc_timestamp(), utc_date(), utc_time(), now(),CURRENT_TIME;
select utc_timestamp(),DATE_FORMAT(utc_timestamp(),'%Y-%m-%d %I:%i:%s'),now();
SELECT CURDATE() + 0;
SELECT '2021-11-26 18:45:28' + 0;
求天数:两段日期之间的天数差
SELECT NOW();
SELECT TO_DAYS('2021-11-25');
SELECT TO_DAYS( NOW());
SELECT TO_DAYS(20211125);
SELECT TO_DAYS(211125);
SELECT TO_DAYS('0000-00-00');
SELECT TO_DAYS('0000-00-01');
SELECT TO_DAYS('0000-01-01');
SELECT TO_DAYS('0001-00-00');
SELECT TO_DAYS('0001-01-00');
SELECT TO_DAYS('0001-01-01');
SELECT TO_DAYS('2021-11-25') -TO_DAYS('2021-11-25') ;
SELECT TO_DAYS(now()) -TO_DAYS('2021-11-25') ;
SELECT TO_DAYS(now()) -TO_DAYS('2021-11-24') ;
SELECT TO_DAYS(now()) -TO_DAYS(20211124) ;
SELECT TO_DAYS(now()) -TO_DAYS(211124) ;
select * from 表 where to_days('字段名')='2021-11-25'
select * from admin where to_days(now())-to_days(create_time)=0;
select * from admin where to_days(now())-to_days(create_time)=1;
select * from admin where to_days(now())-to_days(create_time)<2
select * from admin where to_days(now())-to_days(create_time)>=1
select * from admin where to_days(now())-to_days(create_time)<2
and to_days(now())-to_days(create_time)>=1
SELECT DATEDIFF(now(),'2018-11-13')
SELECT day(now())-DAY('2018-11-13')
这块扩展 注意: to_days()函数此函数与FROM_DAYS()函数相反 。
FROM_DAYS()函数使用方法及示例
SELECT FROM_DAYS(now());
SELECT FROM_DAYS("2021-11-25");
SELECT FROM_DAYS(2021);
SELECT FROM_DAYS(738484);
SELECT DATE_ADD('2021-11-25 23:59:59', INTERVAL 1 SECOND);
select DATE_ADD('2010-12-31 23:59:59', INTERVAL 1 SECOND);
select DATE_ADD('2010-12-31 23:59:59', INTERVAL 1 DAY);
SELECT DATE_ADD('2011-01-01 00:00:00', INTERVAL '-1 10' DAY_HOUR);
SELECT DATE_SUB('2011-01-02', INTERVAL 31 DAY);
SELECT date_add('2011-01-01', INTERVAL -1 DAY);
SELECT FROM_UNIXTIME( 1290996580 )
SELECT DATE_FORMAT( FROM_UNIXTIME( 1290996580 ), '%Y-%m-%d %H:%i:%s' );
SELECT DATE_FORMAT( FROM_UNIXTIME( 1290996580 ) , '%Y-%m-%d' );
FROM_UNIXTIME(unix_timestamp) ;
FROM_UNIXTIME(unix_timestamp,format);
字符串转换为日期格式
可以看到,str_to_date(str,format) 转换函数,可以把一些杂乱无章的字符串转换为日期格式。
select date_format('2008-08-08 22:23:01', '%Y%m%d%H%i%s');
select str_to_date('08/09/2008', '%m/%d/%Y');
select str_to_date('08/09/08' , '%m/%d/%y');
select str_to_date('08.09.2008', '%m.%d.%Y');
select str_to_date('08,2008,09', '%m,%Y,%d');
select str_to_date('08:09:30', '%h:%i:%s');
select str_to_date('08.09.2008 08:09:30', '%m.%d.%Y %h:%i:%s');
将时间、日期转换为字符串 日期转换函数、时间转换函数
(日期/时间转换为字符串)函数:date_format(date,format), time_format(time,format)
能够把一个日期/时间转换成各种各样的字符串格式。它是 (字符串转换为日期)str_to_date(str,format) 函数的 一个逆转换。
date_format,一种是time_format。
先说一下这两者,time_format 只支持时分秒的格式化,对年月日时不起作用的,而 date_format对于年月日时分秒或者两者分开都起作用。 所以使用date_format的即可知道有这个函数就行。
语法:select time_format(time, format_mask) time 必须项。格式化的时间 format_mask 必须项。要使用的格式。可以是以下之一或组合:
SELECT now(); -- 2021-11-25 17:14:16
SELECT TIME_FORMAT(now(), "%H %i %s"); -- 17 14 16
SELECT DATE_FORMAT(now(), "%H %i %s"); -- 17 14 16
time_format 规定日时间的输出格式。
格式 | 描述 |
---|
%f | 微秒(000000至999999) | %H | 小时(00到23) | %h | 小时(00到12) | %I | 小时(00到12) | %i | 分钟(00至59) | %p | 上午或下午 | %r | 时间为12小时AM或PM格式(hh:mm:ss AM / PM) | %S | 秒(00到59) | %s | 秒(00到59) | %T | 24小时格式的时间(hh:mm:ss) |
format 规定日期/时间的输出格式。
格式 | 描述 |
---|
%a | 缩写星期名 | %b | 缩写月名 | %c | 月,数值 | %D | 带有英文前缀的月中的天 | %d | 月的天,数值(00-31) | %e | 月的天,数值(0-31) | %f | 微秒 | %H | 小时 (00-23) | %h | 小时 (01-12) | %I | 小时 (01-12) | %i | 分钟,数值(00-59) | %j | 年的天 (001-366) | %k | 小时 (0-23) | %l | 小时 (1-12) | %M | 月名 | %m | 月,数值(00-12) | %p | AM 或 PM | %r | 时间,12-小时(hh:mm:ss AM 或 PM) | %S | 秒(00-59) | %s | 秒(00-59) | %T | 时间, 24-小时 (hh:mm:ss) | %U | 周 (00-53) 星期日是一周的第一天 | %u | 周 (00-53) 星期一是一周的第一天 | %V | 周 (01-53) 星期日是一周的第一天,与 %X 使用 | %v | 周 (01-53) 星期一是一周的第一天,与 %x 使用 | %W | 星期名 | %w | 周的天 (0=星期日, 6=星期六) | %X | 年,其中的星期日是周的第一天,4 位,与 %V 使用 | %x | 年,其中的星期一是周的第一天,4 位,与 %v 使用 | %Y | 年,4 位 | %y | 年,2 位 |
MySQL (日期、天数)转换函数:to_days(date), from_days(days) 上面有不再赘述
TO_DAYS(date)给出一个日期 `date`,返回一个天数(从 0 年开始的天数):
FROM_DAYS(N)给出一个天数 `N`,返回一个 `DATE` 值:
MySQL (时间、秒)转换函数:time_to_sec(time), sec_to_time(seconds)
time_to_sec 的作用 将指定时间转换为秒
语法:TIME_TO_SEC(time)
time:传入时间,如果传入了日期部分,也不会管,只将时间部分转换成秒
重点:是指将传入的时间转换成距离当天00:00:00的秒数,00:00:00为基数,等于 0 秒
---------时间转秒---------
select now(); -- 2021-11-25 17:32:39
select TIME_TO_SEC(now()); -- 63159
select TIME_TO_SEC('2021-11-25 17:32:39'); -- 63159
select TIME_TO_SEC('17:32:39'); -- 63159
select TIME_TO_SEC('00:00:00'); -- 0
select TIME_TO_SEC('00:01:00'); -- 60
#验证:select 17*3600+32*60+39 -- 63159
---------秒转时间---------
select sec_to_time(63159); -- 17:32:39
MySQL 拼凑日期、时间函数:makdedate(year,dayofyear), maketime(hour,minute,second)
select makedate(2021,31); -- 2021-01-31
select makedate(2021,32); -- 2021-02-01
select makedate(2021,36); -- 2021-02-05
select maketime(12,15,30); -- 12:15:30
select maketime( 17,32,39); -- 17:32:39
MySQL (Unix 时间戳、日期)转换函数
select unix_timestamp();
select unix_timestamp('2008-08-08');
select unix_timestamp('2008-08-08 12:30:00');
select from_unixtime(1218169790);
select from_unixtime(1218124800);
select from_unixtime(1218169800);
select from_unixtime(1218169800, '%Y %D %M %h:%i:%s %x');
MySQL 日期时间计算函数
-- month 月份 minute 分钟 second 秒 hour 小时 week 周 quarter 刻 year 年
select date_sub('1998-01-01 00:00:00', interval '1 1:1:1' day_second) -- 1997-12-30 22:58:59
select date_sub('2021-11-25 17:32:39', interval '1 1:1:1' day_second) -- 2021-11-24 16:31:38
#MySQL 为日期增加一个时间间隔:date_add()
set @dt = now();
select date_add(@dt, interval 1 day); -- 2021-11-26 19:43:19
select date_add(@dt, interval 1 hour); -- 2021-11-25 20:43:19
select date_add(@dt, interval 1 minute);-- 2021-11-25 19:44:19
select date_add(@dt, interval 1 second); -- 2021-11-25 19:43:20
select date_add(@dt, interval 1 microsecond);-- 2021-11-25 19:43:19.000001
select date_add(@dt, interval 1 week);-- 2021-12-02 19:43:19
select date_add(@dt, interval 1 month);-- 2021-12-25 19:43:19
select date_add(@dt, interval 1 quarter); -- 2022-02-25 19:43:19
select date_add(@dt, interval 1 year);-- 2022-11-25 19:43:19
select date_add(@dt, interval -1 day); -- 2021-11-24 19:43:19
#MySQL adddate(), addtime()函数,可以用 date_add() 来替代。下面是 date_add() 实现 addtime() 功能示例:
set @dt = '2008-08-09 12:12:33';
select date_add(@dt, interval '01:15:30' hour_second);-- 2008-08-09 13:28:03
select date_add(@dt, interval '1 01:15:30' day_second);-- 2008-08-10 13:28:03
#MySQL 为日期减去一个时间间隔:date_sub()
select date_sub('1998-01-01 00:00:00', interval '1 1:1:1' day_second);-- 1997-12-30 22:58:59
#对于某个日期加上n分钟n秒
date_add('2018-06-26 23:59:59',INTERVAL '1:1' MINUTE_SECOND)-- 2018-06-27 00:01:00
#对于某个日期加上n小时n分钟n秒
select date_add('2018-06-26 23:59:59',INTERVAL '1:1:1' HOUR_SECOND)-- 2018-06-27 01:01:00
#对某个日期加上n小时n分钟
select date_add('2018-06-26 23:59:59',INTERVAL '1:1' HOUR_MINUTE);-- 2018-06-27 01:00:59
#对某个日期加上几天几小时几分钟几秒钟
select date_add('2018-06-26 23:59:59',INTERVAL '2 2:1:1' DAY_SECOND);-- 2018-06-29 02:01:00
#ADDTIME函数:时间加法运算 将 expr2添加至expr 然后返回结果。 expr 是一个时间或时间日期表达式,而expr2 是一个时间表达式。
SELECT ADDTIME('2007-12-31 23:59:59.999999', '1 1:1:1.000002'); -- 2008-01-02 01:01:01.000001
SELECT ADDTIME('2007-12-31 23:59:58', '1 1:1:1'); -- 2008-01-02 01:00:59
SELECT ADDTIME('01:00:00.999999', '02:00:00.999998'); -- 03:00:01.999997
SELECT ADDTIME('01:00:01', '02:00:01'); -- 03:00:02
select ADDTIME('2015-01-31 16:27:08',1);-- 2015-01-31 16:27:09
select ADDTIME('2015-01-31 16:27:08',59); -- 2015-01-31 16:28:07
select ADDTIME('10:30:59','5:10:37') -- 15:41:36
-- date_add函数的type属性可以动态么? 下面这么写会报错
select num,DATE_ADD(now(),INTERVAL 2 (CASE num WHEN 1 THEN DAY WHEN 2 THEN MONTH WHEN 3 THEN YEAR ELSE YEAR END))
-- 换个思路修改为:
select num , CASE num
WHEN 1 THEN DATE_ADD(now(),INTERVAL 2 DAY)
WHEN 2 THEN DATE_ADD(now(),INTERVAL 2 MONTH)
WHEN 3 THEN DATE_ADD(now(),INTERVAL 2 YEAR)
ELSE DATE_ADD(now(),INTERVAL 2 YEAR)
END from admin
日期、时间相减函数:datediff(date1,date2), timediff(time1,time2)
前面操作日期得到天数 后面操作时间的 且参数都必须是相同的类型,不然结果为空
而TIMESTAMPDIFF比较有意思 能设置返回值属性 并且是第二个日期减去第一个日期
select datediff('2008-08-01', '2008-08-08'); -- -7
select timediff('2008-08-08 08:08:08', '2008-08-08 00:00:00'); -- 08:08:08
select timediff('2008-08-09 08:08:08', '2008-08-08 00:00:00'); -- 32:08:08
select timediff('08:08:08', '00:00:00'); -- 08:08:08
#datediff(date1,date2) 函数 值为date1- date2 得到一个天数整数差 时分秒会忽略掉
SELECT DATEDIFF('2017-11-30','2017-11-29') AS COL1,-- 1
DATEDIFF('2017-11-30','2017-12-15') AS col2, -- -15
DATEDIFF('2017-11-30 08:08:08','2017-12-15') AS col3, -- -15
DATEDIFF('2017-11-30 08:08:08','2017-12-15 08:08:06') AS col4; -- -15
#timestampdiff函数日期或日期时间表达式之间的整数差。
#语法:TIMESTAMPDIFF(interval,datetime1,datetime2),比较的单位interval可以为以下数值
#FRAC_SECOND。表示间隔是毫秒 SECOND。秒 MINUTE。分钟 HOUR。小时 DAY。天
#WEEK。星期 MONTH。月 QUARTER。季度 YEAR。年
#请注意:DATEDIFF,TIMESTAMPDIFF对日期差值的计算方式刚好是相反的。
#计算方式为datetime2-datetime1的差值。
#留意跟时分秒挂钩 会影响结果 少一秒你的结果就得减去1
-- 根据需求 如果可以建议去掉时分秒
select TIMESTAMPDIFF(DAY,'2018-07-01 23:59:59','2018-07-04 23:59:59'); -- 3
select TIMESTAMPDIFF(DAY,'2018-07-01 23:59:59','2018-07-04 23:59:58'); -- 2
select TIMESTAMPDIFF(second,'2018-07-04 23:59:59','2018-07-04 23:59:58'); -- -1
select TIMESTAMPDIFF(second,'2018-07-04 23:59:58','2018-07-04 23:59:59'); -- 1
select TIMESTAMPDIFF(MONTH,'2018-07-01 00:00:00','2018-07-31 23:59:59'); -- 0
select TIMESTAMPDIFF(MONTH,'2018-07-01 00:00:01','2018-08-01 00:00:00'); -- 0
select TIMESTAMPDIFF(MONTH,'2018-07-01 23:59:59','2018-08-01 23:59:58'); -- 0
select TIMESTAMPDIFF(MONTH,'2018-07-01 00:00:00','2018-08-01 00:00:00'); -- 1
select TIMESTAMPDIFF(HOUR,'2018-07-04 23:00:00','2018-07-04 23:59:59'); -- 0
select TIMESTAMPDIFF(HOUR,'2018-07-04 23:00:00','2018-07-05 00:00:00'); -- 1
select TIMESTAMPDIFF(WEEK,'2018-07-04 23:59:59','2018-07-11 23:59:58'); -- 0
select TIMESTAMPDIFF(WEEK,'2018-07-04 23:59:59','2018-07-11 23:59:59'); -- 1
select TIMESTAMPDIFF(WEEK,'2018-07-05 23:59:59','2018-07-12 00:00:00'); -- 0
select TIMESTAMPDIFF(WEEK,'2018-07-05 00:00:00','2018-07-12 00:00:00'); -- 1
select TIMESTAMPDIFF(WEEK,'2018-07-05 00:00:01','2018-07-12 00:00:00'); -- 0
-- 如果需要获取大于时分秒的类型就用年月日格式 时分秒的依旧可以获取到对应的值但值意义不大这时用时分秒年月日格式即可
select TIMESTAMPDIFF(HOUR,'2018-07-04','2018-07-05'); -- 24
select TIMESTAMPDIFF(WEEK,'2018-07-04','2018-07-11'); -- 1
-- 且两者都必须是相同的类型,不然结果为空。
SELECT TIMEDIFF('2018-05-21 14:51:43','2018-05-19 12:54:43');-- 49:57:00
SELECT TIMEDIFF('2018-05-21','2018-05-19');-- 00:00:00
SELECT TIMEDIFF('14:51:43','12:54:43');-- 01:57:00
time_to_sec(timediff (time1,time2))
-- TIMESTAMPDIFF 跟 time_to_sec(timediff (time1,time2)) 都可以用来求秒数 但是有点不同
#但如果时间差比较大,超出timediff 的限制(timediff最大值:838:59:59即:34天22小时59分59秒),得出的结果就是一样的,因为timediff只计算时分秒,不计算 年月日
select time_to_sec(timediff('08:08:08','00:00:00')) -- 29288 = 8*60*60+8*60+8
select time_to_sec(timediff('23:59:58','23:59:59')) -- -1
SELECT TIMEDIFF('2018-05-21 14:51:43','2018-05-19 12:54:43');-- 49:57:00
select time_to_sec(timediff('2018-05-21 14:51:43','2018-05-19 12:54:43')) -- 179820 = 49*60*60+57*60
select time_to_sec(TIMESTAMPDIFF(second,'2018-07-04 23:59:59','2018-07-04 23:59:58')) -- -1
select TIMESTAMPDIFF(second,'2018-07-04 23:59:59','2018-07-04 23:59:58');-- -1
select time_to_sec(TIMESTAMPDIFF(second,'2018-07-04 23:59:59','2018-07-04 23:58:58')) -- null 只要年月日时分不一致就是空 跟TIMESTAMPDIFF配合使用的话年月日时分必须的保持一致 换句话TIMESTAMPDIFF函数我都已经求出秒数了 也没必要在搭配time_to_sec 画蛇添足
select TIMESTAMPDIFF(second,'2018-07-04 23:59:59','2018-07-05 23:59:58') -- 86399
select timediff('2018-06-21 23:59:59','2018-05-18 01:01:01') -- 838:58:58 这个多一秒永远的值都是 838:59:59
select time_to_sec(timediff('2018-06-21 23:59:59','2018-05-18 01:01:01')) ;-- 3020338 = 838*60*60+58*60+58
select time_to_sec(timediff('2018-06-21 23:59:59','2018-05-18 01:01:00')) ;-- 3020339 这个多一秒永远的值都是 3020339
select time_to_sec(timediff('2018-06-21 23:59:59','2018-05-18 01:00:00')) ;-- 3020399
#注:sql很活 都能拿到一致的结果情况下优先使用最优解函数
-- 计算日期是星期几 DAYOFWEEK(date)
SELECT DAYOFWEEK('2021-11-26') AS '今天是星期几'; -- 6 实际星期5
-- 计算本月是第几天 DAYOFMONTH(date)
SELECT DAYOFMONTH('2021-11-26') AS '本月第几天';-- 26
-- 计算本年是第几天DAYOFYEAR(date)
SELECT DAYOFYEAR('2021-11-26') AS '本年第几天';-- 330 最优解
SELECT TO_DAYS('2021-11-26')-TO_DAYS('2021-01-01')+1 AS '本年第几天';-- 330
SELECT DATEDIFF('2021-11-26','2021-01-01')+1 AS '本年第几天';-- 330
SELECT TIMESTAMPDIFF(day,'2021-01-01','2021-11-26')+1 AS '本年第几天';-- 330
-- 计算本年是第几月份 MONTH(date)
SELECT MONTH('2021-11-26') AS '本年第几月份'; -- 11
-- 计算本年是第几季度 QUARTER(date)
SELECT QUARTER('2021-11-26') AS '本年第几季度'; -- 4
mysql 判断闰年
#判断2月份是不是28天
SELECT DAY
(
LAST_DAY(
DATE_ADD(
DATE_ADD(
DATE_ADD( CURRENT_DATE, INTERVAL - DAYOFYEAR( CURRENT_DATE ) DAY ),
INTERVAL 1 DAY
),
INTERVAL 1 MONTH
)
)
)
#if判断法:
select IF(((YEAR(now()) % 4 = 0 AND YEAR(now()) % 100 != 0) OR YEAR(now()) % 400 = 0) ,0,1)
date_add(date,interval if(day(birthday)=29&&day(date)=28,1,0) day)
MySQL根据出生日期计算年龄
#方法一:缺陷就是当日期为未来日期时结果为0,而不是负数;这里使用了5个函数和两个运算符。
SELECT DATE_FORMAT(FROM_DAYS(TO_DAYS(NOW())-TO_DAYS('1994-04-28')), '%Y')+0 AS age
#方法二:解决了方法一为负数的问题,但看起来更复杂;这里使用了6个函数和3个运算符。
SELECT DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT('1994-04-28', '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT('1994-04-28', '00-%m-%d')) AS age
# 综合一、二版本:=======================建议使用=========================
SELECT year( from_days( datediff( now( ), '1994-04-28')));-- 一
SELECT YEAR(CURDATE())-YEAR('1994-04-28')-(RIGHT(CURDATE(),5)<RIGHT('1994-04-28',5));-- 二
#方法三:取生日和当前日期之前的天数除以一年的实际天数(365天5小时48分46秒),然后取整。这样只用了三个函数和一个运算符就搞定了。
SELECT FLOOR(DATEDIFF(CURDATE(), '1994-04-28')/365.2422)
#方法四
SELECT TIMESTAMPDIFF(YEAR,'1994-04-28', CURDATE())
#方法五
SELECT ROUND(DATEDIFF(CURDATE(), '1994-04-28')/365.2422)
时间戳(timestamp)转换、增、减函数:
时间戳的更多知识点击获取
#注:踩坑点 TIMESTAMP值不能比1970早,也不能比2037晚,这意味着,一个日期例如'1968-01-01',当作为一个 DATETIME或DATE值时它是合法的,但它不是一个正确TIMESTAMP值!并且如果将这样的一个对象赋值给TIMESTAMP列,它将被变换为 0。
#当指定日期值时,当心某些缺陷:
#1.允许作为字符串指定值的宽松格式能被欺骗。例如,因为“:”分隔符的使用,值'10:11:12'可能看起来像时间值,但是如果在一个日期中使用,上下文将作为年份被解释成'2010-11-12'。值'10:45:15'将被变换到'0000-00-00',因为'45'不是一个合法的月份。
#2.以2位数字指定的年值是模糊的,因为世纪是未知的。MySQL使用下列规则解释2位年值:在00-69范围的年值被变换到2000-2069。 在范围70-99的年值被变换到1970-1999。三、当指定日期值时,当心某些缺陷:
#时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。
#在MySQL上述三个大版本中,默认时间戳(Timestamp)类型的取值范围为'1970-01-01 00:00:01' UTC 至'2038-01-19 03:14:07' UTC,数据精确到秒级别,该取值范围包含约22亿个数值,因此在MySQL内部使用4个字节INT类型来存放时间戳数据:
#1、在存储时间戳数据时,先将本地时区时间转换为UTC时区时间,再将UTC时区时间转换为INT格式的毫秒值(使用UNIX_TIMESTAMP函数),然后存放到数据库中。
#2、在读取时间戳数据时,先将INT格式的毫秒值转换为UTC时区时间(使用FROM_UNIXTIME函数),然后再转换为本地时区时间,最后返回给客户端。
#在MySQL上述三个大版本中,默认时间戳(Timestamp)类型的取值范围为'1970-01-01 00:00:01' UTC 至'2038-01-19 03:14:07' UTC,数据精确到秒级别,该取值范围包含约22亿个数值,因此在MySQL内部使用4个字节INT类型来存放时间戳数据:
#1、在存储时间戳数据时,先将本地时区时间转换为UTC时区时间,再将UTC时区时间转换为INT格式的毫秒值(使用UNIX_TIMESTAMP函数),然后存放到数据库中。
#2、在读取时间戳数据时,先将INT格式的毫秒值转换为UTC时区时间(使用FROM_UNIXTIME函数),然后再转换为本地时区时间,最后返回给客户端。
时间戳字段定义主要影响两类操作:在创建新记录和修改现有记录的时候都对这个数据列刷新
插入记录时,时间戳字段包含DEFAULT CURRENT_TIMESTAMP,如插入记录时未指定具体时间数据则将该时间戳字段值设置为当前时间
更新记录时,时间戳字段包含ON UPDATE CURRENT_TIMESTAMP,如更新记录时未指定具体时间数据则将该时间戳字段值设置为当前时间
#语法1: timestamp(date) -- date to timestamp 语法2:timestamp(dt,time)-- dt + time
select timestamp(now()); -- 2021-11-27 01:21:48
select timestamp(CURRENT_DATE); -- 2021-11-27 00:00:00 -- 时间部分被设置为'00:00:00',因为DATE值中不包含有时间信息。
select timestamp('2008-08-08'); -- 2008-08-08 00:00:00
select timestamp('2008-08-08 08:00:00', '01:01:01'); -- 2008-08-08 09:01:01
select timestamp('2008-08-08 08:00:00', '10 01:01:01'); -- 2008-08-18 09:01:01
#语法:timestampadd(unit,interval,datetime_expr) unit值跟TIMESTAMPDIFF一致
select timestampadd(day, 1, '2008-08-08 08:00:00'); -- 2008-08-09 08:00:00
select timestampadd(day, 1, '2008-08-08'); -- 2008-08-09
#语法 timestampdiff(unit,datetime_expr1,datetime_expr2) -- 上文已存在
#MySQL timestampadd() 函数类似于 date_add()。
select date_add('2008-08-08 08:00:00', interval 1 day); -- 2008-08-09 08:00:00
#MySQL timestampdiff() 函数就比 datediff() 功能强多了,datediff() 只能计算两个日期(date)之间相差的天数。
select timestampdiff(year,'2002-05-01','2001-01-01'); -- -1
select timestampdiff(day ,'2002-05-01','2001-01-01'); -- -485
select timestampdiff(hour,'2008-08-08 12:00:00','2008-08-08 00:00:00'); -- -12
select datediff('2008-08-08 23:59:59', '2008-08-01 00:00:00'); -- 7 只看年月日
select datediff('2008-08-08', '2008-08-01'); -- 7
MySQL 时区(timezone)转换函数
#语法:convert_tz(dt,from_tz,to_tz)
select convert_tz('2008-08-08 12:00:00', '+08:00', '+00:00'); -- 2008-08-08 04:00:00
SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');-- 2004-01-01 22:00:00
SELECT CONVERT_TZ('2020-11-19 19:59:00', '+00:00', '+05:30') -- 2020-11-20 01:29:00
SELECT CONVERT_TZ('2020-11-19', '+00:00', '+05:30') -- 2020-11-19 05:30:00
select CONVERT_TZ('2020-11-19 10:53:00', '+00:00', '+05:30') ;-- 2020-11-19 16:23:00
select CONVERT_TZ('2020-11-19 10:53:00', '-05:00', '+05:30') ;-- 2020-11-19 21:23:00
select CONVERT_TZ('2020-11-19 10:53:00' , '+00:00', '-05:00');-- 2020-11-19 05:53:00
select CONVERT_TZ('2020-11-19 10:53:00' , '+05:30', '-05:00');-- 2020-11-19 00:23:00
-- 总结:先算后再算前 后边符号不变 前边取相反符号 算出来是多少就是多少
#时区转换也可以通过 date_add, date_sub, timestampadd 来实现。
select date_add('2008-08-08 12:00:00', interval -8 hour); -- 2008-08-08 04:00:00
select date_sub('2008-08-08 12:00:00', interval 8 hour); -- 2008-08-08 04:00:00
select timestampadd(hour, -8, '2008-08-08 12:00:00'); -- 2008-08-08 04:00:00
关于 date_add()等type的取值
date 参数是合法的日期表达式。expr 参数是您希望添加的时间间隔。
type 参数可以是下列值:
Type 值 |
---|
MICROSECOND | SECOND | MINUTE | HOUR | DAY | WEEK | MONTH | QUARTER | YEAR | SECOND_MICROSECOND | MINUTE_MICROSECOND | MINUTE_SECOND | HOUR_MICROSECOND | HOUR_SECOND | HOUR_MINUTE | DAY_MICROSECOND | DAY_SECOND | DAY_MINUTE | DAY_HOUR | YEAR_MONTH |
日期类总结
获得当前时间:NOW(); curdate(); CURRENT_DATE();(sysdate()用的少,在需要函数执行时动态得到值在用它)
CURTIME();获取时分秒
获得当前时间戳函数: CURRENT_TIME(); CURRENT_TIMESTAMP();
日期/时间 转换为字符串函数:date_format(date,format), time_format(time,format)
混乱字符串转换为日期函数:str_to_date(str, format)
日期、天数 转换函数:to_days(date), from_days(days)
时间、秒 转换函数:time_to_sec(time), sec_to_time(seconds)
冷门SQL
DATE_FORMAT() 把日期进行格式化,FROM_UNIXTIME() 把时间戳格式化成一个日期,UNIX_TIMESTAMP() 正好相反,把日期格式化成时间戳。
注:FROM_UNIXTIME 默认 年月日时分秒格式 如果需要其他日期格式需要在加上日期格式
SELECT UNIX_TIMESTAMP(20101129100940), UNIX_TIMESTAMP(101129100940);
SELECT FROM_UNIXTIME(1290996580),FROM_UNIXTIME(1290996580,'%Y-%m-%d %H:%i:%s') as var10 ;
SELECT UNIX_TIMESTAMP(20101129), UNIX_TIMESTAMP(101129);
SELECT FROM_UNIXTIME(1290960000),
FROM_UNIXTIME(1290960000,'%Y-%m-%d') ;
SELECT FROM_UNIXTIME(1290996580) as var1,
FROM_UNIXTIME(1290996580,'MMdd-yyyy') as var2,
FROM_UNIXTIME(1290996580,'') as var3,
FROM_UNIXTIME(1290996580,'nullstr') as var4,
FROM_UNIXTIME(1290996580,null) as var5,
FROM_UNIXTIME(1290996580,'%Y%m%d') as var6 ,
FROM_UNIXTIME(1290996580,'%Y年%m月%d') as var7 ;
SELECT FROM_UNIXTIME( 1290996580 )
SELECT UNIX_TIMESTAMP() ,
UNIX_TIMESTAMP('2010-11-29'),
UNIX_TIMESTAMP(2010-11-29),
UNIX_TIMESTAMP(20101129),
UNIX_TIMESTAMP(101129),
UNIX_TIMESTAMP(20101129100940),
UNIX_TIMESTAMP(101129100940);
SELECT FROM_UNIXTIME(1290960000) as var1,
FROM_UNIXTIME(1290960000,'MMdd-yyyy') as var2,
FROM_UNIXTIME(1290960000,'') as var3,
FROM_UNIXTIME(1290960000,'nullstr') as var4,
FROM_UNIXTIME(1290960000,null) as var5 ,
FROM_UNIXTIME(1290960000,'%Y%m%d') as var6 ,
FROM_UNIXTIME(1290960000,'%Y年%m月%d') as var7 ,
FROM_UNIXTIME(1290960000,'%Y-%m-%d %H:%m:%s') as var8 ,
FROM_UNIXTIME(1290960000,'%Y-%m-%d %H:%i:%s') as var9 ,
FROM_UNIXTIME(1290996580,'%Y-%m-%d %H:%i:%s') as var10 ;
详细练习
时间函数练习
Mysql查询“当天、昨天、上周、本月、上一季、本年”的SQL语句
今天
select * from 表名 where to_days(时间字段名) = to_days(now());
或者
select * from 表名 where to_days(时间字段名) -to_days(now())=0;
昨天
SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ) - TO_DAYS( 时间字段名) <= 1
and TO_DAYS( NOW( ) ) - TO_DAYS( 时间字段名) != 0
上面固然可以实现毕竟很麻烦 建议使用更贴切的函数
SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 1 DAY) = DATE_FORMAT(时间字段名,'%Y-%m-%d')
select DATE_SUB(CURDATE(), INTERVAL 1 DAY)
select DATE_SUB(CURDATE(), INTERVAL 0 DAY)
select DATE_SUB(CURDATE(), INTERVAL -1 DAY)
近7天
SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(时间字段名)
近30天
SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= date(时间字段名)
本月
SELECT * FROM 表名 WHERE DATE_FORMAT( 时间字段名, '%Y%m' ) = DATE_FORMAT( CURDATE( ) , '%Y%m' )
上一月
SELECT * FROM 表名 WHERE PERIOD_DIFF( date_format( now( ) , '%Y%m' ) , date_format( 时间字段名, '%Y%m' ) ) =1
查询本季度数据
select * from `ht_invoice_information` where QUARTER(create_date)=QUARTER(now())
查询上季度数据
select * from `ht_invoice_information` where QUARTER(create_date)=QUARTER(DATE_SUB(now(),interval 1 QUARTER));
查询本年数据
select * from `ht_invoice_information` where YEAR(create_date)=YEAR(NOW());
查询上年数据
select * from `ht_invoice_information` where year(create_date)=year(date_sub(now(),interval 1 year));
查询当前这周的数据
SELECT name,submittime FROM enterprise WHERE YEARWEEK(date_format(submittime,'%Y-%m-%d')) = YEARWEEK(now());
查询上周的数据
SELECT name,submittime FROM enterprise WHERE YEARWEEK(date_format(submittime,'%Y-%m-%d')) = YEARWEEK(now())-1;
查询上个月的数据
select name,submittime from enterprise where date_format(submittime,'%Y-%m')=date_format(DATE_SUB(curdate(), INTERVAL 1 MONTH),'%Y-%m')
select * from user where DATE_FORMAT(pudate,'%Y%m') = DATE_FORMAT(CURDATE(),'%Y%m') ;
select * from user where WEEKOFYEAR(FROM_UNIXTIME(pudate,'%y-%m-%d')) = WEEKOFYEAR(now())
select * from user where MONTH(FROM_UNIXTIME(pudate,'%y-%m-%d')) = MONTH(now())
select * from user where YEAR(FROM_UNIXTIME(pudate,'%y-%m-%d')) = YEAR(now()) and MONTH(FROM_UNIXTIME(pudate,'%y-%m-%d')) = MONTH(now())
select * from user where pudate between 上月最后一天 and 下月第一天
查询当前月份的数据
select name,submittime from enterprise where date_format(submittime,'%Y-%m')=date_format(now(),'%Y-%m')
查询距离当前现在6个月的数据
select name,submittime from enterprise where submittime between date_sub(now(),interval 6 month) and now();
动态sql语句基本语法:https://bbs.csdn.net/topics/280007702
https://bbs.csdn.net/topics/310162964?list=9107182
动态sql语句基本语法:https://bbs.csdn.net/topics/280007702
https://bbs.csdn.net/topics/310162964?list=9107182
作者:远看寒山石径斜链接:https://www.imooc.com/article/71440
|