前言:
上次寫了查詢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 BOOLEANBEGIN /*是閏年則返回0(false),不是閏年則返回1(true)*/ DECLARE v_flag?INT ?DEFAULT ?0; /*①、普通年能被4整除且不能被100整除的為閏年。(如2004年就是閏年,1901年不是閏年)*/ IF?( p_year% 4) = 0?AND ?( p_year% 100) > 0?THEN SET ?v_flag= 0; ?/*②、世紀年能被400整除的是閏年。(如2000年是閏年,1900年不是閏年) */ ELSEIF?( p_year% 400) = 0?THEN SET ?v_flag= 0; ?/*③、對于數值非常大的年份,這年假設能整除3200,而且能整除172800則是閏年。如172800年是閏年, 86400年不是閏年(由于盡管能整除3200,但不能整除172800)(此按一回歸年365天5h48\'45.5\'\'計算)。 */ ELSEIF?( p_year% 3200) = 0?AND ?( p_year% 172800) = 0?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 ?4OR /* 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 ?4OR ?/*補充閏年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) ; 運行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日问题的解决过程 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。