MySQL日期和时间函数讲解

1. NOW、CURRENT_TIMESTAMP和SYSDATE mysql

这些函数都能返回当前的系统时间,它们之间有区别吗?先来看个例子。 sql

mysql> SELECT NOW(),CURRENT_TIMESTAMP(),SYSDATE()\G;
*************************** 1. row ***************************
NOW(): 2011-02-04 20:35:04
CURRENT_TIMESTAMP(): 2011-02-04 20:35:04
SYSDATE(): 2011-02-04 20:35:04 函数

从上面的例子看来,3个函数都是返回当前的系统时间,再来看下面这个例子: 优化

mysql>SELECT
->     NOW(),
->     CURRENT_TIMESTAMP(),
->     SYSDATE(),
->     SLEEP(2),
->     NOW(),
->     CURRENT_TIMESTAMP(),
->     SYSDATE()\G
*************************** 1. row ***************************
NOW(): 2011-11-29 21:04:49
CURRENT_TIMESTAMP(): 2011-11-29 21:04:49
SYSDATE(): 2011-11-29 21:04:49
SLEEP(2): 0
NOW(): 2011-11-29 21:04:49
CURRENT_TIMESTAMP(): 2011-11-29 21:04:49
SYSDATE(): 2011-11-29 21:04:51
1 row in set (2.00 sec) spa

在上面这个例子中人为地加入了SLEEP函数,让其等待2秒,这时能够发现SYSDATE返回的时间和NOW及CURRENT_TIMESTAMP是不一样的,SYSDATE函数慢了2秒。究其缘由是这3个函数有略微区别: 索引

CURRENT_TIMESTAMP是NOW的同义词,也就是说二者是相同的。 开发

SYSDATE函数返回的是执行到当前函数时的时间,而NOW返回的是执行SQL语句时的时间。 it

所以在上面的例子中,两次执行SYSDATE函数返回不一样的时间是由于第二次调用执行该函数时等待了前面SLEEP函数2秒。而对于NOW函数,无论是在SLEEP函数以前仍是以后执行,返回的都是执行这条SQL语句时的时间。 table

2.时间加减函数 效率

先来看一个例子。

mysql> SELECT NOW(),NOW()+0\G;
*************************** 1. row ***************************
NOW(): 2011-02-04 20:46:33
NOW()+0: 20110204204633.000000
1 row in set (0.00 sec)

能够看到,NOW()函数能够返回时间,也能够返回一个数字,就看用户如何使用。若是相对当前时间进行增长或减小,并不能直接加上或减去一个数字,而须要使用特定的函数,如DATE_ADD或DATE_SUB,前者表示增长,后者表示减小。其具体的使用方法有DATE_ADD(date,INTERVAL expr unit)和 DATE_SUB(date,INTERVAL expr unit),示例以下:

mysql> SELECT NOW() AS now,
DATE_ADD(now(),INTERVAL 1 DAY) AS tomorrow,
DATE_SUB(now(),INTERVAL 1 DAY) AS yesterday\G;
*************************** 1. row ***************************
now: 2011-02-04 20:53:25
tomorrow: 2011-02-05 20:53:25
yesterday: 2011-02-03 20:53:25
1 row in set (0.00 sec)

其中expr值能够是正值也能够是负值,所以可使用DATE_ADD函数来完成DATE_SUB函数的工做,例如:

mysql> SELECT NOW() AS now,
DATE_ADD(NOW(),INTERVAL 1 DAY) AS tomorrow,
DATE_ADD(NOW(),INTERVAL -1 DAY) AS yesterday\G;
*************************** 1. row ***************************
now: 2011-02-04 20:55:40
tomorrow: 2011-02-05 20:55:40
yesterday: 2011-02-03 20:55:40
1 row in set (0.00 sec)

还有一个问题,若是是闰月,那么DATE_ADD函数怎么处理呢?MySQL的默认行为是这样的:若是目标年份是闰月,那么返回的日期为2月29日;若是不是闰月,那么返回日期是2月28日。示例以下:

mysql> SELECT DATE_ADD(’2000-2-29′,INTERVAL 4 YEAR) AS year;
+————+
| year        |
+————+
| 2004-02-29 |
+————+
1 row in set (0.00 sec)

 

mysql> SELECT DATE_ADD(’2000-2-29′,INTERVAL 1 YEAR) AS year;
+————+
| year        |
+————+
| 2001-02-28 |
+————+
1 row in set (0.00 sec)

在上面的例子中使用了DAY和YEAR数据类型,其实也可使用MICROSECOND、SECOND、MINUTE、HOUR、WEEK、MONTH等类型,例如:

mysql> SELECT NOW() AS now,
DATE_ADD(NOW(), INTERVAL 1 HOUR) AS next time\G;
*************************** 1. row ***************************
now: 2011-02-04 21:00:15
next time: 2011-02-04 22:00:15
1 row in set (0.00 sec)

 3. DATE_FORMAT函数

这个函数自己没有什么须要探讨的地方,其做用只是按照用户的需求格式化打印出日期,例如:

mysql> SELECT DATE_FORMAT(NOW(),’%Y%m%d’) AS datetime;
+———-+
| datetime |
+———-+
| 20110204 |
+———-+
1 row in set (0.00 sec)

可是开发人员每每会错误地使用这个函数,致使很是严重的后果。例如在须要查询某一天的数据时,有些开发人员会写以下的语句:

SELECT * FROM table WHERE DATE_FORMAT(date,’%Y%m%d’)=’xxxx-xx-xx’;

通常来讲表中都会有一个对日期类型的索引,若是使用上述的语句,优化器绝对不会使用索引,也不可能经过索引来查询数据,所以上述查询的执行效率可能很是低。

相关文章
相关标签/搜索