欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 运维知识 > 数据库 >内容正文

数据库

[MySQL]--gt;查询5天之内过生日的同事中的闰年2月29日问题的解决过程

发布时间:2024/4/14 数据库 53 豆豆
生活随笔 收集整理的这篇文章主要介绍了 [MySQL]--gt;查询5天之内过生日的同事中的闰年2月29日问题的解决过程 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

前言:

上次写了查询5天之内过生日的同事中的跨年问题的解决过程,网址为:http://blog.csdn.net/mchdba/article/details/38952033 ,当中漏了一个闰年2月29日生日的细节问题,如今补充一下这个问题的处理过程:

5,补充闰年推断

有朋友提醒,闰年2月29日生日的话,可能查询不到,想到确实没有考虑到这个特殊的日期。
5.1,准备測试数据SQL,包括1980-02-29这一天生日的朋友。
INSERT INTO ali_users  SELECT 'Jeff','1980-02-29','13998786549' 
UNION ALL SELECT 'WeiYa','1980-02-28','13998786549' 
UNION ALL SELECT 'XiaoTeng','1980-03-01','13998786549' 
UNION ALL SELECT 'HeSheng','1980-03-02','13998786549'
UNION ALL SELECT 'JingPan','1980-03-03','13998786549'
UNION ALL SELECT 'WuHong','1986-03-04','13998786549';

5.2,录入測试数据
  • mysql> use test;
  • Reading table information for completion of table and column names
  • You can turn off this feature to get a quicker startup with -A

  • Database changed
  • mysql> INSERT INTO ali_users SELECT \'Jeff\',\'1980-02-29\',\'13998786549\' UNION ALL SELECT \'XiaoTeng\',\'1980-03-01\',\'13998786549\' 
  •     -> UNION ALL SELECT \'HeSheng\',\'1980-03-02\',\'13998786549\'
  •     -> UNION ALL SELECT \'JingPan\',\'1980-03-03\',\'13998786549\'
  •     -> UNION ALL SELECT \'WuHong\',\'1986-03-04\',\'13998786549\';
  • Query OK, 5 rows affected (0.00 sec)
  • Records: 5 Duplicates: 0 Warnings: 0

  • mysql>

  • 5.3,运行原来的旧版本号的SQL查询检查结果

    把Step#2中的SQL的NOW()改成'2014-02-28 00:10:10'来进行測试,确实没有包括2月29日生日的同事,例如以下所看到的:
  • mysql> SELECT * FROM ali_users WHERE 
  •     -> DATEDIFF(CAST(CONCAT(YEAR(\'2014-02-28 00:10:10\'),DATE_FORMAT(birthday,\'-%m-%d\'))AS DATE),CAST(DATE_FORMAT(\'2014-02-28 00:10:10\',\'%y-%m-%d\') AS DATE)) BETWEEN 0 AND 4
  •     -> OR/* or后面的是捎带解决跨年问题*/ 
  •     -> DATEDIFF(CAST(CONCAT(YEAR(\'2014-02-28 00:10:10\')+1,DATE_FORMAT(birthday,\'-%m-%d\'))AS DATE),CAST(DATE_FORMAT(\'2014-02-28 00:10:10\',\'%y-%m-%d\') AS DATE)) BETWEEN 0 AND 4
  •     -> ;
  • +----------+------------+-------------+
  • | username | birthday | iphone |
  • +----------+------------+-------------+
  • | XiaoTeng | 1980-03-01 | 13998786549 |
  • | HeSheng | 1980-03-02 | 13998786549 |
  • | JingPan | 1980-03-03 | 13998786549 |
  • | WuHong | 1986-03-04 | 13998786549 |
  • +----------+------------+-------------+
  • 4 rows in set, 2 warnings (0.00 sec)


  • mysql>

  • 5.4,先建立一个存储函数f_isleap_year推断当年年份是否是闰年
    5.4.1 准备推断是否闰年的SQL
  • DELIMITER $$
  • USE `test`$$
  • DROP FUNCTION IF EXISTS `f_not_leap_year`$$
  • CREATE FUNCTION `f_not_leap_year`(p_year BIGINT) RETURNS BOOLEAN
  • BEGIN
  • /*是闰年则返回0(false),不是闰年则返回1(true)*/
  • DECLARE v_flag INT DEFAULT 0;
  • /*①、普通年能被4整除且不能被100整除的为闰年。(如2004年就是闰年,1901年不是闰年)*/
  • IF (p_year%4)=AND (p_year%100)>THEN
  • SET v_flag=0; 
  • /*②、世纪年能被400整除的是闰年。(如2000年是闰年,1900年不是闰年) */
  • ELSEIF (p_year%400)=THEN
  • SET v_flag=0; 
  • /*③、对于数值非常大的年份,这年假设能整除3200,而且能整除172800则是闰年。如172800年是闰年,
  • 86400年不是闰年(由于尽管能整除3200,但不能整除172800)(此按一回归年365天5h48\'45.5\'\'计算)。
  • */
  • ELSEIF (p_year%3200)=AND (p_year%172800)=THEN
  • SET v_flag=0;
  • ELSE
  • SET v_flag=1;
  • END IF;
  • RETURN v_flag;
  •  END$$
  • DELIMITER ;

  • 存储函数运行例如以下图所看到的:
     


    5.4.2 准备SQL语句

  • SELECT * FROM ali_users WHERE 
  • DATEDIFF(CAST(CONCAT(YEAR(NOW()),DATE_FORMAT(birthday,\'-%m-%d\'))AS DATE),CAST(DATE_FORMAT(NOW(),\'%y-%m-%d\') AS DATE)) BETWEEN 0 AND 4
  • OR/* or后面的是捎带解决跨年问题*/ 
  • DATEDIFF(CAST(CONCAT(YEAR(NOW())+1,DATE_FORMAT(birthday,\'-%m-%d\'))AS DATE),CAST(DATE_FORMAT(NOW(),\'%y-%m-%d\') AS DATE)) BETWEEN 0 AND 4
  • OR /*补充闰年2月29日的生日问题*/
  • (
  • f_not_leap_year(YEAR(NOW()))
  • AND DATE_FORMAT(birthday,\'-%m-%d\')=\'-02-29\' 
  • AND DATEDIFF(CAST(CONCAT(\'2000\',DATE_FORMAT(birthday,\'-%m-%d\'))AS DATE),CAST(CONCAT(\'2000\',DATE_FORMAT(NOW(),\'-%m-%d\')) AS DATE)) 
  • BETWEEN 0 AND 4
  • );

  • 5.4.3 在非闰年的时候,验证闰年2月29日生日,选择2014年非闰年測试
    把Step#2中的SQL的NOW()改成'2014-02-28 00:10:10'来进行測试,SQL例如以下所看到的:
    SELECT * FROM ali_users WHERE 
    DATEDIFF(CAST(CONCAT(YEAR('2014-02-28 00:10:10'),DATE_FORMAT(birthday,'-%m-%d'))AS DATE),CAST(DATE_FORMAT('2014-02-28 00:10:10','%y-%m-%d') AS DATE)) BETWEEN 0 AND 4
    OR/* or后面的是捎带解决跨年问题*/ 
    DATEDIFF(CAST(CONCAT(YEAR('2014-02-28 00:10:10')+1,DATE_FORMAT(birthday,'-%m-%d'))AS DATE),CAST(DATE_FORMAT('2014-02-28 00:10:10','%y-%m-%d') AS DATE)) BETWEEN 0 AND 4
    OR /*补充闰年2月29日的生日方法*/
    (
    f_not_leap_year(YEAR('2014-02-28 00:10:10')) 
    AND DATE_FORMAT(birthday,'-%m-%d')='-02-29' 
    AND DATEDIFF(CAST(CONCAT('2000',DATE_FORMAT(birthday,'-%m-%d'))AS DATE),CAST(CONCAT('2000',DATE_FORMAT('2000-02-28 00:10:10','-%m-%d')) AS DATE)) 
    BETWEEN 0 AND 4
    );

    运行SQL检验成果,假设当天是2014-02-28,看到已经有2月29日的生日的同事被记录进来了,事实上包括了2月28日、2月29日、3月1日、3月2日、3月3日、3月4日的生日的同事。
    PS:由于2月29日在当年不存在,所以不算这5天之内的范畴,运行结果例如以下所看到的:
  • mysql> SELECT * FROM ali_users WHERE 
  •     -> DATEDIFF(CAST(CONCAT(YEAR(\'2014-02-28 00:10:10\'),DATE_FORMAT(birthday,\'-%m-%d\'))AS DATE),CAST(DATE_FORMAT(\'2014-02-28 00:10:10\',\'%y-%m-%d\') AS DATE)) BETWEEN 0 AND 4
  •     -> OR/* or后面的是捎带解决跨年问题*/ 
  •     -> DATEDIFF(CAST(CONCAT(YEAR(\'2014-02-28 00:10:10\')+1,DATE_FORMAT(birthday,\'-%m-%d\'))AS DATE),CAST(DATE_FORMAT(\'2014-02-28 00:10:10\',\'%y-%m-%d\') AS DATE)) BETWEEN 0 AND 4
  •     -> OR /*补充闰年2月29日的生日方法*/
  •     -> (
  •     -> f_not_leap_year(YEAR(\'2014-02-28 00:10:10\')) 
  •     -> AND DATE_FORMAT(birthday,\'-%m-%d\')=\'-02-29\' 
  •     -> AND DATEDIFF(CAST(CONCAT(\'2000\',DATE_FORMAT(birthday,\'-%m-%d\'))AS DATE),CAST(CONCAT(\'2000\',DATE_FORMAT(\'2000-02-28 00:10:10\',\'-%m-%d\')) AS DATE)) 
  •     -> BETWEEN 0 AND 4
  •     -> );
  • +----------+------------+-------------+
  • | username | birthday | iphone |
  • +----------+------------+-------------+
  • | Jeff | 1980-02-29 | 13998786549 |
  • | XiaoTeng | 1980-03-01 | 13998786549 |
  • | HeSheng | 1980-03-02 | 13998786549 |
  • | JingPan | 1980-03-03 | 13998786549 |
  • | WuHong | 1986-03-04 | 13998786549 |
  • | WeiYa | 1980-02-28 | 13998786549 |
  • +----------+------------+-------------+
  • 6 rows in set, 2 warnings (0.00 sec)


  • mysql>

  • 5.4.4 在闰年的时候,验证闰年2月29日生日,选择2004年闰年測试
    把Step#2中的SQL的NOW()改成'2004-02-28 00:10:10'来进行測试,SQL例如以下所看到的:
  • SELECT * FROM ali_users WHERE 
  • DATEDIFF(CAST(CONCAT(YEAR(\'2004-02-28 00:10:10\'),DATE_FORMAT(birthday,\'-%m-%d\'))AS DATE),CAST(DATE_FORMAT(\'2004-02-28 00:10:10\',\'%y-%m-%d\') AS DATE)) BETWEEN 0 AND 4
  • OR/* or后面的是捎带解决跨年问题*/ 
  • DATEDIFF(CAST(CONCAT(YEAR(\'2004-02-28 00:10:10\')+1,DATE_FORMAT(birthday,\'-%m-%d\'))AS DATE),CAST(DATE_FORMAT(\'2004-02-28 00:10:10\',\'%y-%m-%d\') AS DATE)) BETWEEN 0 AND 4
  • OR /*补充闰年2月29日的生日方法*/
  • (
  • f_not_leap_year(YEAR(\'2004-02-28 00:10:10\')) 
  • AND DATE_FORMAT(birthday,\'-%m-%d\')=\'-02-29\' 
  • AND DATEDIFF(CAST(CONCAT(\'2000\',DATE_FORMAT(birthday,\'-%m-%d\'))AS DATE),CAST(CONCAT(\'2000\',DATE_FORMAT(\'2004-02-28 00:10:10\',\'-%m-%d\')) ASDATE)) 
  • BETWEEN 0 AND 4
  • );

  • 运行SQL检验成果,假设当天是2004-02-28,看到已经有2月29日的生日的同事被记录进来了,事实上包括了2月28日、2月29日、3月1日、3月2日、3月3日的生日的同事。
    PS:由于2月29日在当年存在,所以算这5天之内的范畴,运行结果例如以下所看到的:

  • mysql> SELECT * FROM ali_users WHERE 
  •     -> DATEDIFF(CAST(CONCAT(YEAR(\'2004-02-28 00:10:10\'),DATE_FORMAT(birthday,\'-%m-%d\'))AS DATE),CAST(DATE_FORMAT(\'2004-02-28 00:10:10\',\'%y-%m-%d\') AS DATE)) BETWEEN 0 AND 4
  •     -> OR/* or后面的是捎带解决跨年问题*/ 
  •     -> DATEDIFF(CAST(CONCAT(YEAR(\'2004-02-28 00:10:10\')+1,DATE_FORMAT(birthday,\'-%m-%d\'))AS DATE),CAST(DATE_FORMAT(\'2004-02-28 00:10:10\',\'%y-%m-%d\') AS DATE)) BETWEEN 0 AND 4
  •     -> OR /*补充闰年2月29日的生日方法*/
  •     -> (
  •     -> f_not_leap_year(YEAR(\'2004-02-28 00:10:10\')) 
  •     -> AND DATE_FORMAT(birthday,\'-%m-%d\')=\'-02-29\' 
  •     -> AND DATEDIFF(CAST(CONCAT(\'2000\',DATE_FORMAT(birthday,\'-%m-%d\'))AS DATE),CAST(CONCAT(\'2000\',DATE_FORMAT(\'2004-02-28 00:10:10\',\'-%m-%d\')) AS DATE)) 
  •     -> BETWEEN 0 AND 4
  •     -> );
  • +----------+------------+-------------+
  • | username | birthday | iphone |
  • +----------+------------+-------------+
  • | Jeff | 1980-02-29 | 13998786549 |
  • | XiaoTeng | 1980-03-01 | 13998786549 |
  • | HeSheng | 1980-03-02 | 13998786549 |
  • | JingPan | 1980-03-03 | 13998786549 |
  • | WeiYa | 1980-02-28 | 13998786549 |
  • +----------+------------+-------------+
  • 5 rows in set (0.00 sec)


  • mysql>
  • 总结

    以上是生活随笔为你收集整理的[MySQL]--gt;查询5天之内过生日的同事中的闰年2月29日问题的解决过程的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。