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’;

通常來講表中都會有一個對日期類型的索引,若是使用上述的語句,優化器絕對不會使用索引,也不可能經過索引來查詢數據,所以上述查詢的執行效率可能很是低。

相關文章
相關標籤/搜索