> For the complete documentation index, see [llms.txt](https://404dream.gitbook.io/mysql/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://404dream.gitbook.io/mysql/summary/creating-and-using-a-database/retrieving-information-from-a-table/date-calculations.md).

# 4.3.4.5 日期计算

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 |
+----------+------------+------------+------+
```

要按年龄而不是名称对输出进行排序，只需使用不同的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 |
+----------+------------+------------+------+
```

类似的查询可以用于确定死亡的动物的死亡年龄。你通过检查死亡值是否为NULL来确定这些动物。然后，对于那些具有非NULL值的计算死亡和出生值之间的差异：

```
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是一个特殊的值，无法使用通常的比较运算符进行比较。这将在后面讨论。请参见Section 4.3.4.6, “Working with NULL Values”.。

如果你想知道哪些动物下个月有生日怎么办？对于这种类型的计算，年和日是不相关的;你只需要提取出生列的月部分。 MySQL提供了几种提取日期部分的功能，例如YEAR()，MONTH()和DAYOFMONTH()。 MONTH()是这里适当的函数。要查看它是如何工作，运行一个简单的查询，显示出生和MONTH（出生）的值：

```
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月。然后月值是4，你可以寻找出生在5月（第5个月）的动物，如下所示：

```
mysql>SELECT name, birth FROM pet WHERE MONTH(birth) = 5;
+-------+------------+
| name  | birth      |
+-------+------------+
| Buffy | 1989-05-13 |
+-------+------------+
```

如果当月是12月，有一个小问题。你不能只是添加一个月份（12），并寻找在13个月出生的动物，因为没有这样的月份。相反，你寻找在1月（第1个月）出生的动物。

您可以编写查询语句，以使其工作，无论当前月份是什么，以便您不必使用特定月份的数字。 DATE\_ADD()使您能够向给定日期添加时间间隔。如果向CURDATE（）的值添加一个月，则使用MONTH（）提取月份部分，结果将生成查找生日的月份：

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

另一种方法是在使用求余函数(MOD)后将当前值加1以获得下一个月，如果当前值为12，则将月值包装为0：

```
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)。
