1.3.4.5 日期运算

MySQL 提供一些函数用于日期的运算,比如说:计算年龄或提供日期中的年、月、日信息;

比方说,您想知道所有宠物的年龄,那么您可以使用 TIMESTAMPDIFF() 函数,该函数有3个参数,分别是提取的单位、开始日期、结束日期,下面的语句显示了每一个宠物的 name、birth、CURDATE()、age(别名) :

mysql> select name,CURDATE(),birth,TIMESTAMPDIFF(YEAR,birth, CURDATE()) as age  
    -> from pet;
+----------------------+------------+------------+------+
| name                 | CURDATE()  | birth      | age  |
+----------------------+------------+------------+------+
| Fluffy               | 2017-12-20 | 1993-02-04 |   24 |
| Claws                | 2017-12-20 | 1994-03-17 |   23 |
| Buffy                | 2017-12-20 | 1989-05-13 |   28 |
| Fang                 | 2017-12-20 | 1990-08-27 |   27 |
| Bowser               | 2017-12-20 | 1989-08-30 |   28 |
| Chirpy               | 2017-12-20 | 1998-09-11 |   19 |
| Whistler             | 2017-12-20 | 1997-12-09 |   20 |
| Slim                 | 2017-12-20 | 1996-04-29 |   21 |
| Puffball             | 2017-12-20 | 1999-03-30 |   18 |
+----------------------+------------+------------+------+
9 rows in set (0.01 sec)
Note

TIMESTAMPDIFF 函数的第一个参数可选值包括:MICROSECOND (微秒)、SECOND、MINUTE、HOUR、DAY、WEEK, MONTH、QUARTER(季度)、YEAR;其中 MICROSECOND 是5.0版本替换 FRAC_SECOND(毫秒),5.5 版本之后 FRAC_SECOND 正式废弃。第二、第三参数必需 Y-m-d H:i:s 的日期格式 或其省略格式,例如:Y-m-d、Y-m-d H等

对上面的检索结果进行排序,将更方便浏览检索结果:

按照 name 进行排序:

mysql> select name,CURDATE(),birth,TIMESTAMPDIFF(YEAR,birth, CURDATE()) as age
    -> from pet
    -> order by name;
+----------------------+------------+------------+------+
| name                 | CURDATE()  | birth      | age  |
+----------------------+------------+------------+------+
| Bowser               | 2017-12-20 | 1989-08-30 |   28 |
| Buffy                | 2017-12-20 | 1989-05-13 |   28 |
| Chirpy               | 2017-12-20 | 1998-09-11 |   19 |
| Claws                | 2017-12-20 | 1994-03-17 |   23 |
| Fang                 | 2017-12-20 | 1990-08-27 |   27 |
| Fluffy               | 2017-12-20 | 1993-02-04 |   24 |
| Puffball             | 2017-12-20 | 1999-03-30 |   18 |
| Slim                 | 2017-12-20 | 1996-04-29 |   21 |
| Whistler             | 2017-12-20 | 1997-12-09 |   20 |
+----------------------+------------+------------+------+
9 rows in set (0.00 sec)

按照 age 降序排序

mysql> select name,CURDATE(),birth,TIMESTAMPDIFF(YEAR,birth, CURDATE()) as age
    -> from pet
    -> order by age desc;
+----------------------+------------+------------+------+
| name                 | CURDATE()  | birth      | age  |
+----------------------+------------+------------+------+
| Buffy                | 2017-12-20 | 1989-05-13 |   28 |
| Bowser               | 2017-12-20 | 1989-08-30 |   28 |
| Fang                 | 2017-12-20 | 1990-08-27 |   27 |
| Fluffy               | 2017-12-20 | 1993-02-04 |   24 |
| Claws                | 2017-12-20 | 1994-03-17 |   23 |
| Slim                 | 2017-12-20 | 1996-04-29 |   21 |
| Whistler             | 2017-12-20 | 1997-12-09 |   20 |
| Chirpy               | 2017-12-20 | 1998-09-11 |   19 |
| Puffball             | 2017-12-20 | 1999-03-30 |   18 |
+----------------------+------------+------------+------+
9 rows in set (0.00 sec)

相似的,我们要检索已死亡宠物的年龄,那么首先,要确定宠物是否死亡?判断 death 是否为 NULL。其次使用函数 TIMESTAMPDIFF ,计算死亡年龄。

mysql> select name,birth,death,
    -> TIMESTAMPDIFF(YEAR,birth,death) as age
    -> from pet
    -> where death is not NULL
    -> order by age desc;
+----------------------+------------+------------+------+
| name                 | birth      | death      | age  |
+----------------------+------------+------------+------+
| Bowser               | 1989-08-30 | 1995-07-29 |    5 |
+----------------------+------------+------------+------+
1 row in set (0.00 sec)
Note

在 MySQL 中,NULL是一个特殊的值,不能使用常用的算术运行符进行比较,如 <> NULL、!= NULL等 ,都不能得到期望的结果,在下一节中,我们将介绍 MySQL 中的 NULL 值。

如果您想知道下个月有哪些宠物需要过生日?对于这种计算和年份、日份无关,我们仅需要知道月份。在 MySQL 中提供了多个函数,用于提取部分日期,例如:year()、month()、day()、dayofmonth(),下面是一个简单示例,显示宠物的出生日期和出生月份。

mysql> select name,birth,month(birth) as birthMonth 
    -> from pet
    -> order by birthMonth;
+----------------------+------------+------------+
| name                 | birth      | birthMonth |
+----------------------+------------+------------+
| Fluffy               | 1993-02-04 |          2 |
| Claws                | 1994-03-17 |          3 |
| Puffball             | 1999-03-30 |          3 |
| Slim                 | 1996-04-29 |          4 |
| Buffy                | 1989-05-13 |          5 |
| Fang                 | 1990-08-27 |          8 |
| Bowser               | 1989-08-30 |          8 |
| Chirpy               | 1998-09-11 |          9 |
| Whistler             | 1997-12-09 |         12 |
+----------------------+------------+------------+
9 rows in set (0.00 sec)
mysql> select name,birth,day(birth) as birthDay from pet;
mysql> select name,birth,year(birth) as birthYear from pet;

如果您要查询当前 8 月份,有哪些宠物生日,那么您也可以执行如下的操作:

mysql> SELECT name, birth, month(birth) as monthBirth FROM pet WHERE month(birth) = 8;
+----------------------+------------+------------+
| name                 | birth      | monthBirth |
+----------------------+------------+------------+
| Fang                 | 1990-08-27 |          8 |
| Bowser               | 1989-08-30 |          8 |
+----------------------+------------+------------+
2 rows in set (0.00 sec)
Tips:

此处您可能会有一个疑问,为什么不使用 SELECT name, birth, month(birth) as monthBirth FROM pet WHERE monthBirth = 8; 如果您执行该语句,会出现 ERROR 1054 (42S22): Unknown column 'monthBirth' in 'where clause' 的错误。但是,您使用 SELECT name, birth, month(birth) as monthBirth FROM pet order by monthBirth; 却能显示正常结果,即别名分别出现在 whereorder by 的不同字句中。

那么,别名到底出现在哪些字句中可以执行?哪些字句中不能执行?我们需要了解 SELECT 的执行顺序,请阅读:1.3.4.10 SELECT的执行顺序

您还可以进行其他的一些日期运算

mysql> SELECT name, birth FROM pet
    -> WHERE MONTH(birth) = MONTH(DATE_ADD(CURDATE(),INTERVAL 1 MONTH));
mysql> SELECT name, birth FROM pet
    -> WHERE MONTH(birth) = MOD(MONTH(CURDATE()), 12) + 1;

本章的内容仅是介绍日期运算的入门知识,更详细关于日期的运算请看后续章节。

results matching ""

    No results matching ""