zoukankan      html  css  js  c++  java
  • mysql时间相减的问题

    mysql时间相减的问题(bug)

        今天看到宁青同学的一条微博,提到MySQL日期相减的错误结果,以前没有怎么注意,于是测试了一下,发现确实很坑爹,很容易踩雷,于是整理博客提醒一下大家。
    先看一下错误的现象如下,第1条正确,第2,3条的t2-t1不正确:

    [sql] view plain copy
    1. mysql> select t1,t2,t2-t1 from mytest;  
    2. +---------------------+---------------------+-------+  
    3. | t1                  | t2                  | t2-t1 |  
    4. +---------------------+---------------------+-------+  
    5. | 2013-04-21 16:59:33 | 2013-04-21 16:59:43 |    10 |  
    6. | 2013-04-21 16:59:33 | 2013-04-21 17:00:33 |  4100 |  
    7. | 2013-04-21 16:59:33 | 2013-04-21 17:59:35 | 10002 |  
    8. +---------------------+---------------------+-------+  
    9. rows in set  


    全部测试脚本如下:

    [sql] view plain copy
    1. --创建表  
    2. mysql> CREATE TABLE mytest (  
    3.   t1 datetime,  
    4.   t2 datetime  
    5. );  
    6. Query OK, 0 rows affected  
    7. --插入测试记录  
    8. mysql> insert into mytest(t1,t2) values('2013-04-21 16:59:33','2013-04-21 16:59:43');  
    9. Query OK, 1 row affected  
    10.   
    11. mysql> insert into mytest(t1,t2) values('2013-04-21 16:59:33','2013-04-21 17:00:33');  
    12. Query OK, 1 row affected  
    13.   
    14. mysql> insert into mytest(t1,t2) values('2013-04-21 16:59:33','2013-04-21 17:59:35');  
    15. Query OK, 1 row affected  
    16. --验证结果  
    17. mysql> select t1,t2,t2-t1 from mytest;  
    18. +---------------------+---------------------+-------+  
    19. | t1                  | t2                  | t2-t1 |  
    20. +---------------------+---------------------+-------+  
    21. | 2013-04-21 16:59:33 | 2013-04-21 16:59:43 |    10 |  
    22. | 2013-04-21 16:59:33 | 2013-04-21 17:00:33 |  4100 |  
    23. | 2013-04-21 16:59:33 | 2013-04-21 17:59:35 | 10002 |  
    24. +---------------------+---------------------+-------+  
    25. rows in set  


    实际是mysql的时间相减是做了一个隐式转换操作,将时间转换为整数,但并不是用unix_timestamp转换,而是直接把年月日时分秒拼起来,如2013-04-21 16:59:33 直接转换为20130421165933,由于时间不是十进制,所以最后得到的结果没有意义,这也是导致上面出现坑爹的结果。

    [sql] view plain copy
    1. mysql> select t1,  
    2.        t2,  
    3.        convert(t1, UNSIGNED INTEGER) ct1,  
    4.        convert(t2, UNSIGNED INTEGER) ct2,  
    5.        t2-t1,  
    6.        convert(t2, UNSIGNED INTEGER) -convert(t1, UNSIGNED INTEGER) diff0  
    7.   from mytest;   
    8. +-------------------+-------------------+--------------+--------------+-----+-----+  
    9. |t1                 |t2                 |ct1           |ct2           |t2-t1|diff0|  
    10. +-------------------+-------------------+--------------+--------------+-----+-----+  
    11. |2013-04-21 16:59:33|2013-04-21 16:59:43|20130421165933|20130421165943|   10|   10|  
    12. |2013-04-21 16:59:33|2013-04-21 17:00:33|20130421165933|20130421170033| 4100| 4100|  
    13. |2013-04-21 16:59:33|2013-04-21 17:59:35|20130421165933|20130421175935|10002|10002|  
    14. +-------------------+-------------------+--------------+--------------+-----+-----+  
    15. rows in set  


    要得到正确的时间相减秒值,有以下3种方法:
    1、time_to_sec(timediff(t2, t1)),
    2、timestampdiff(second, t1, t2),
    3、unix_timestamp(t2) -unix_timestamp(t1)

    [sql] view plain copy
    1. --测试脚本  
    2. mysql> select t1,  
    3.        t2,  
    4.        t2-t1,  
    5.        time_to_sec(timediff(t2, t1)) diff1,  
    6.        timestampdiff(second, t1, t2) diff2,  
    7.        unix_timestamp(t2) -unix_timestamp(t1) diff3  
    8.   from mytest;  
    9. +---------------------+---------------------+-------+-------+-------+-------+  
    10. | t1                  | t2                  | t2-t1 | diff1 | diff2 | diff3 |  
    11. +---------------------+---------------------+-------+-------+-------+-------+  
    12. | 2013-04-21 16:59:33 | 2013-04-21 16:59:43 |    10 |    10 |    10 |    10 |  
    13. | 2013-04-21 16:59:33 | 2013-04-21 17:00:33 |  4100 |    60 |    60 |    60 |  
    14. | 2013-04-21 16:59:33 | 2013-04-21 17:59:35 | 10002 |  3602 |  3602 |  3602 |  
    15. +---------------------+---------------------+-------+-------+-------+-------+  
    16. rows in set  


    这个问题2003年就有人在mysql4.0的版本时反馈,但mysql官方并不认为是bug,因为他们认为mysql并不支持时间直接相减操作,应该用专用函数处理,所以一直没有修正。但我认为这个很容易导致使用错误,要么就直接报错,要么显示正确的结果。

    我的新浪微博 http://weibo.com/yzsind

  • 相关阅读:
    浅谈Huffman树
    CF884D:Boxes And Balls
    MySQL单表查询(重要)
    MySQL字段完整性约束(重要)
    MySQL数据类型(重要)
    数据库基本操作
    MySQL权限管理
    MySQL存储引擎概述
    数据库基础
    并发编程小结
  • 原文地址:https://www.cnblogs.com/ningxu/p/6840024.html
Copyright © 2011-2022 走看看