MySQL 提供了几个函数,您可以使用它们来执行日期计算,例如,计算年龄或提取部分日期。

    要确定每只宠物的年龄,请使用 TIMESTAMPDIFF() 函数。它的参数是你想要表达结果的单位,以及取差的两个日期。以下查询显示了每只宠物的出生日期、当前日期和年龄(以年为单位)。别名(年龄)用于使最终输出的列标签更有意义。

    1. mysql> SELECT name, birth, CURDATE(),
    2. TIMESTAMPDIFF(YEAR,birth,CURDATE()) AS age
    3. FROM pet;
    4. +----------+------------+------------+------+
    5. | name | birth | CURDATE() | age |
    6. +----------+------------+------------+------+
    7. | Fluffy | 1993-02-04 | 2003-08-19 | 10 |
    8. | Claws | 1994-03-17 | 2003-08-19 | 9 |
    9. | Buffy | 1989-05-13 | 2003-08-19 | 14 |
    10. | Fang | 1990-08-27 | 2003-08-19 | 12 |
    11. | Bowser | 1989-08-31 | 2003-08-19 | 13 |
    12. | Chirpy | 1998-09-11 | 2003-08-19 | 4 |
    13. | Whistler | 1997-12-09 | 2003-08-19 | 5 |
    14. | Slim | 1996-04-29 | 2003-08-19 | 7 |
    15. | Puffball | 1999-03-30 | 2003-08-19 | 4 |
    16. +----------+------------+------------+------+

    查询有效,但如果以某种顺序显示行,则可以更轻松地扫描结果。这可以通过添加 ORDER BY name 子句来按名称对输出进行排序来完成:

    1. mysql> SELECT name, birth, CURDATE(),
    2. TIMESTAMPDIFF(YEAR,birth,CURDATE()) AS age
    3. FROM pet ORDER BY name;
    4. +----------+------------+------------+------+
    5. | name | birth | CURDATE() | age |
    6. +----------+------------+------------+------+
    7. | Bowser | 1989-08-31 | 2003-08-19 | 13 |
    8. | Buffy | 1989-05-13 | 2003-08-19 | 14 |
    9. | Chirpy | 1998-09-11 | 2003-08-19 | 4 |
    10. | Claws | 1994-03-17 | 2003-08-19 | 9 |
    11. | Fang | 1990-08-27 | 2003-08-19 | 12 |
    12. | Fluffy | 1993-02-04 | 2003-08-19 | 10 |
    13. | Puffball | 1999-03-30 | 2003-08-19 | 4 |
    14. | Slim | 1996-04-29 | 2003-08-19 | 7 |
    15. | Whistler | 1997-12-09 | 2003-08-19 | 5 |
    16. +----------+------------+------------+------+

    要按年龄而不是名称对输出进行排序,只需使用不同的 ORDER BY 子句:

    1. mysql> SELECT name, birth, CURDATE(),
    2. TIMESTAMPDIFF(YEAR,birth,CURDATE()) AS age
    3. FROM pet ORDER BY age;
    4. +----------+------------+------------+------+
    5. | name | birth | CURDATE() | age |
    6. +----------+------------+------------+------+
    7. | Chirpy | 1998-09-11 | 2003-08-19 | 4 |
    8. | Puffball | 1999-03-30 | 2003-08-19 | 4 |
    9. | Whistler | 1997-12-09 | 2003-08-19 | 5 |
    10. | Slim | 1996-04-29 | 2003-08-19 | 7 |
    11. | Claws | 1994-03-17 | 2003-08-19 | 9 |
    12. | Fluffy | 1993-02-04 | 2003-08-19 | 10 |
    13. | Fang | 1990-08-27 | 2003-08-19 | 12 |
    14. | Bowser | 1989-08-31 | 2003-08-19 | 13 |
    15. | Buffy | 1989-05-13 | 2003-08-19 | 14 |
    16. +----------+------------+------------+------+

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

    1. mysql> SELECT name, birth, death,
    2. TIMESTAMPDIFF(YEAR,birth,death) AS age
    3. FROM pet WHERE death IS NOT NULL ORDER BY age;
    4. +--------+------------+------------+------+
    5. | name | birth | death | age |
    6. +--------+------------+------------+------+
    7. | Bowser | 1989-08-31 | 1995-07-29 | 5 |
    8. +--------+------------+------------+------+

    该查询使用 death IS NOT NULL 而不是 death <> NULL 因为 NULL 是一个特殊值,无法使用通常的比较运算符进行比较。

    如果你想知道哪些动物下个月过生日怎么办?对于这种类型的计算,年份和日期是无关紧要的;您只是想提取出生列的月份部分。 MySQL 提供了几个函数来提取部分日期,例如 YEAR()、MONTH() 和 DAYOFMONTH()。 MONTH() 是这里的适当函数。要查看它是如何工作的,请运行一个显示出生和 MONTH(birth) 值的简单查询:

    1. mysql> SELECT name, birth, MONTH(birth) FROM pet;
    2. +----------+------------+--------------+
    3. | name | birth | MONTH(birth) |
    4. +----------+------------+--------------+
    5. | Fluffy | 1993-02-04 | 2 |
    6. | Claws | 1994-03-17 | 3 |
    7. | Buffy | 1989-05-13 | 5 |
    8. | Fang | 1990-08-27 | 8 |
    9. | Bowser | 1989-08-31 | 8 |
    10. | Chirpy | 1998-09-11 | 9 |
    11. | Whistler | 1997-12-09 | 12 |
    12. | Slim | 1996-04-29 | 4 |
    13. | Puffball | 1999-03-30 | 3 |
    14. +----------+------------+--------------+

    寻找下个月过生日的动物也很简单。假设当前月份是四月。然后月份值为 4,您可以像这样查找 5 月(第 5 个月)出生的动物:

    1. mysql> SELECT name, birth FROM pet WHERE MONTH(birth) = 5;
    2. +-------+------------+
    3. | name | birth |
    4. +-------+------------+
    5. | Buffy | 1989-05-13 |
    6. +-------+------------+

    如果当前月份是 12 月,则会出现一个小问题。您不能只在月份编号 (12) 上加一,然后寻找在第 13 个月出生的动物,因为没有这样的月份。相反,您会寻找 1 月(第 1 个月)出生的动物。

    您可以编写查询,以便无论当前月份是什么月份它都能正常工作,这样您就不必使用特定月份的数字。 DATE_ADD() 使您能够将时间间隔添加到给定日期。如果将月份添加到 CURDATE() 的值,然后使用 MONTH() 提取月份部分,则结果会生成查找生日的月份:

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

    完成相同任务的另一种方法是在使用模函数 (MOD) 将月份值包装为 0(如果当前为 12)后,在当前月份之后加 1 以获取下个月:

    1. mysql> SELECT name, birth FROM pet
    2. WHERE MONTH(birth) = MOD(MONTH(CURDATE()), 12) + 1;

    MONTH() 返回 1 到 12 之间的数字。MOD(something,12) 返回一个介于 0 和 11 之间的数字。所以加法必须在 MOD() 之后,否则我们将从 11 月 (11) 到 1 月 (1)。

    如果计算使用无效日期,则计算失败并产生警告:

    1. mysql> SELECT '2018-10-31' + INTERVAL 1 DAY;
    2. +-------------------------------+
    3. | '2018-10-31' + INTERVAL 1 DAY |
    4. +-------------------------------+
    5. | 2018-11-01 |
    6. +-------------------------------+
    7. mysql> SELECT '2018-10-32' + INTERVAL 1 DAY;
    8. +-------------------------------+
    9. | '2018-10-32' + INTERVAL 1 DAY |
    10. +-------------------------------+
    11. | NULL |
    12. +-------------------------------+
    13. mysql> SHOW WARNINGS;
    14. +---------+------+----------------------------------------+
    15. | Level | Code | Message |
    16. +---------+------+----------------------------------------+
    17. | Warning | 1292 | Incorrect datetime value: '2018-10-32' |
    18. +---------+------+----------------------------------------+