MySQL 提供了數個函數,您可以利用這些函數對日期執行計算,例如,計算年齡或擷取日期的部分。
若要判斷每隻寵物的年齡,請使用 TIMESTAMPDIFF() 函數。其引數為您想要表示結果的單位,以及要計算差異的兩個日期。下列查詢顯示每隻寵物的出生日期、目前日期和年齡(以年為單位)。使用別名(age)使最終輸出欄標籤更有意義。
mysql> SELECT name, birth, CURDATE(),
TIMESTAMPDIFF(YEAR,birth,CURDATE()) AS age
FROM pet;
+----------+------------+------------+------+
| name | birth | CURDATE() | age |
+----------+------------+------------+------+
| Fluffy | 1993-02-04 | 2003-08-19 | 10 |
| Claws | 1994-03-17 | 2003-08-19 | 9 |
| Buffy | 1989-05-13 | 2003-08-19 | 14 |
| Fang | 1990-08-27 | 2003-08-19 | 12 |
| Bowser | 1989-08-31 | 2003-08-19 | 13 |
| Chirpy | 1998-09-11 | 2003-08-19 | 4 |
| Whistler | 1997-12-09 | 2003-08-19 | 5 |
| Slim | 1996-04-29 | 2003-08-19 | 7 |
| Puffball | 1999-03-30 | 2003-08-19 | 4 |
+----------+------------+------------+------+查詢可以運作,但如果以某種順序顯示列,則可以更容易地掃描結果。這可以透過新增 ORDER BY name 子句來依名稱排序輸出來完成
mysql> SELECT name, birth, CURDATE(),
TIMESTAMPDIFF(YEAR,birth,CURDATE()) AS age
FROM pet ORDER BY name;
+----------+------------+------------+------+
| name | birth | CURDATE() | age |
+----------+------------+------------+------+
| Bowser | 1989-08-31 | 2003-08-19 | 13 |
| Buffy | 1989-05-13 | 2003-08-19 | 14 |
| Chirpy | 1998-09-11 | 2003-08-19 | 4 |
| Claws | 1994-03-17 | 2003-08-19 | 9 |
| Fang | 1990-08-27 | 2003-08-19 | 12 |
| Fluffy | 1993-02-04 | 2003-08-19 | 10 |
| Puffball | 1999-03-30 | 2003-08-19 | 4 |
| Slim | 1996-04-29 | 2003-08-19 | 7 |
| Whistler | 1997-12-09 | 2003-08-19 | 5 |
+----------+------------+------------+------+若要依 age 而非 name 排序輸出,只需使用不同的 ORDER BY 子句
mysql> SELECT name, birth, CURDATE(),
TIMESTAMPDIFF(YEAR,birth,CURDATE()) AS age
FROM pet ORDER BY age;
+----------+------------+------------+------+
| name | birth | CURDATE() | age |
+----------+------------+------------+------+
| Chirpy | 1998-09-11 | 2003-08-19 | 4 |
| Puffball | 1999-03-30 | 2003-08-19 | 4 |
| Whistler | 1997-12-09 | 2003-08-19 | 5 |
| Slim | 1996-04-29 | 2003-08-19 | 7 |
| Claws | 1994-03-17 | 2003-08-19 | 9 |
| Fluffy | 1993-02-04 | 2003-08-19 | 10 |
| Fang | 1990-08-27 | 2003-08-19 | 12 |
| Bowser | 1989-08-31 | 2003-08-19 | 13 |
| Buffy | 1989-05-13 | 2003-08-19 | 14 |
+----------+------------+------------+------+可以使用類似的查詢來判斷已死亡動物的死亡年齡。您透過檢查 death 值是否為 NULL 來判斷這些動物。然後,對於具有非 NULL 值的動物,計算 death 和 birth 值之間的差異
mysql> SELECT name, birth, death,
TIMESTAMPDIFF(YEAR,birth,death) AS age
FROM pet WHERE death IS NOT NULL ORDER BY age;
+--------+------------+------------+------+
| name | birth | death | age |
+--------+------------+------------+------+
| Bowser | 1989-08-31 | 1995-07-29 | 5 |
+--------+------------+------------+------+查詢使用 death IS NOT NULL 而非 death <> NULL,因為 NULL 是一個特殊值,無法使用一般的比較運算子進行比較。這將在稍後討論。請參閱第 5.3.4.6 節「處理 NULL 值」。
如果您想知道哪些動物下個月過生日呢?對於這種類型的計算,年份和日期並不重要;您只需要擷取 birth 欄的月份部分。MySQL 提供了數個函數來擷取日期的部分,例如 YEAR()、MONTH() 和 DAYOFMONTH()。MONTH() 在此處是適當的函數。若要查看其運作方式,請執行一個簡單的查詢,顯示 birth 和 MONTH(birth) 的值
mysql> SELECT name, birth, MONTH(birth) FROM pet;
+----------+------------+--------------+
| name | birth | MONTH(birth) |
+----------+------------+--------------+
| Fluffy | 1993-02-04 | 2 |
| Claws | 1994-03-17 | 3 |
| Buffy | 1989-05-13 | 5 |
| Fang | 1990-08-27 | 8 |
| Bowser | 1989-08-31 | 8 |
| Chirpy | 1998-09-11 | 9 |
| Whistler | 1997-12-09 | 12 |
| Slim | 1996-04-29 | 4 |
| Puffball | 1999-03-30 | 3 |
+----------+------------+--------------+尋找下個月過生日的動物也很簡單。假設目前月份為四月。則月份值為 4,您可以像這樣尋找在五月(月份 5)出生的動物
mysql> SELECT name, birth FROM pet WHERE MONTH(birth) = 5;
+-------+------------+
| name | birth |
+-------+------------+
| Buffy | 1989-05-13 |
+-------+------------+如果目前月份是十二月,則會有些小複雜。您不能僅將月份數字 (12) 加一,並尋找在月份 13 出生的動物,因為沒有這樣的月份。相反地,您會尋找在一月(月份 1)出生的動物。
您可以撰寫查詢,使其無論目前月份為何都能運作,因此您不必使用特定月份的數字。DATE_ADD() 可讓您將時間間隔新增至給定的日期。如果您將一個月新增至 CURDATE() 的值,然後使用 MONTH() 擷取月份部分,則結果會產生尋找生日的月份
mysql> SELECT name, birth FROM pet
WHERE MONTH(birth) = MONTH(DATE_ADD(CURDATE(),INTERVAL 1 MONTH));完成相同工作的另一種方法是,在使用模數函數 (MOD) 將月份值包裹為 0(如果目前為 12)之後,加 1 以取得目前月份之後的下一個月份
mysql> SELECT name, birth FROM pet
WHERE MONTH(birth) = MOD(MONTH(CURDATE()), 12) + 1;
MONTH() 傳回介於 1 和 12 之間的數字。MOD(something,12) 則傳回介於 0 和 11 之間的數字。因此,加法必須在 MOD() 之後,否則我們會從十一月 (11) 變成一月 (1)。
如果計算使用無效的日期,則計算會失敗並產生警告
mysql> SELECT '2018-10-31' + INTERVAL 1 DAY;
+-------------------------------+
| '2018-10-31' + INTERVAL 1 DAY |
+-------------------------------+
| 2018-11-01 |
+-------------------------------+
mysql> SELECT '2018-10-32' + INTERVAL 1 DAY;
+-------------------------------+
| '2018-10-32' + INTERVAL 1 DAY |
+-------------------------------+
| NULL |
+-------------------------------+
mysql> SHOW WARNINGS;
+---------+------+----------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------+
| Warning | 1292 | Incorrect datetime value: '2018-10-32' |
+---------+------+----------------------------------------+