mysql > 选择 DATE_ADD (‘2011-03-01‘,INTERVAL -1 DAY ) ;
+ ----------------------------------------- +
| DATE_ADD (‘2011-03-01‘,INTERVAL -1 DAY ) |
+ ----------------------------------------- +
| 2011 -02- 28 |
+ ----------------------------------------- +
1行中 集合 (0.00秒)
mysql > 选择 DATE_ADD (‘2012-03-01‘,INTERVAL -1 DAY ) ;
+ ----------------------------------------- +
| DATE_ADD (‘2012-03-01‘,INTERVAL -1 DAY ) |
+ ----------------------------------------- +
| 2012 -02- 29 |
+ ----------------------------------------- +
1行中 集合 (0.00秒)
mysql > 选择 DATE_ADD (‘2000-03-01‘,INTERVAL -1 DAY ) ;
+ ----------------------------------------- +
| DATE_ADD (‘2000-03-01‘,INTERVAL -1 DAY ) |
+ ----------------------------------------- +
| 2000 -02- 29 |
+ ----------------------------------------- +
1行中 集合 (0.00秒)
mysql > 选择 DATE_ADD (‘1900-03-01‘,INTERVAL -1 DAY ) ;
+ ----------------------------------------- +
| DATE_ADD (‘1900-03-01‘,间隔-1 DAY ) |
+ ----------------------------------------- +
| 1900 -02- 28 |
+ ----------------------------------------- +
1行中 集合 (0.00秒)
所以我们需要做的是使用CONCAT()构建正确的字符串以传递给DATE_ADD,我们可以使用YEAR()和我们的硬连线3月1日轻松完成。
SELECT CONCAT ( YEAR ( CURDATE ()),‘ - 03-01‘ ) ;
+ ----------------------------------- +
| CONCAT ( YEAR ( CURDATE ()),‘-03-01‘ ) |
+ ----------------------------------- +
| 2011年 03 月1日|
+ ----------------------------------- +
1行中 集合 (0.00秒)
这将始终生成相当于当年3月1日的有效mysql日期字符串。现在我们将它替换为DATE_ADD()函数:
SELECT DATE_ADD ( CONCAT ( YEAR ( CURDATE ()),‘ - 03-01‘ ),INTERVAL -1 DAY ) ;
+ ------------------------------------------------- ------------- +
| DATE_ADD ( CONCAT ( YEAR ( CURDATE ()),‘-03-01‘ ),间隔-1 DAY ) |
+ ------------------------------------------------- ------------- +
| 2011 -02- 28 |
+ ------------------------------------------------- ------------- +
1行中 集合 (0.00秒)
当我们在查询中实际使用它时,我们只需要DAY():
SELECT DAY ( DATE_ADD ( CONCAT ( YEAR ( CURDATE ()),‘ - 03-01‘ ),INTERVAL -1 DAY )) ;
+ ------------------------------------------------- ------------------ +
| DAY ( DATE_ADD ( CONCAT ( YEAR ( CURDATE ()),‘-03-01‘ ),间隔-1 DAY )) |
+ ------------------------------------------------- ------------------ +
| 28 |
+ ------------------------------------------------- ------------------ +
然后我们需要添加一个条件,因此如果用户的生日是2月29日,我们只返回此计算。
SELECT *,IF (个月(生日) = 2和日(生日) = 29,‘飞跃‘,‘正常‘ ) 为弹跳FROM用户;
+ ---- + --------- + ------------ + -------- +
| id | 名字 | 生日 | leaper |
+ ---- + --------- + ------------ + -------- +
| 1 | 弗兰 | 1967 - 10 - 31 | 正常|
| 2 | 比尔 | 1964年 - 05 - 07年| 正常|
| 3 | 吉米 | 1965 -04- 27 | 正常|
| 4 | Stacy | 2002 - 11 - 30 | 正常|
| 5 | 乔治 | 2007 - 10 - 25 | 正常|
| 6 | Leapie | 2008 -02-29 | 飞跃 |
| 7 | BadLeap | 0000-00-00 | 正常|
+ ---- + --------- + ------------ + -------- +
7行中 集合 (0.00秒)
由于我们可以看到我们的条件正常工作,剩下的就是插入适当的函数来代替‘Leap‘和‘Normal‘。跳跃将是我们的“3月1日前一天”计算,而“正常”将是原始的DAY(生日)。完成后它可能看起来很神秘,但你可以把它分解成它的组成部分,正如我在本文中所展示的那样,并且希望很明显你可以使用mysql在需要时使用一系列简单的函数来解决相对复杂的问题三元函数。
SELECT *, YEAR ( CURDATE ()) -
YEAR (出生日期) -
IF ( STR_TO_DATE ( CONCAT ( YEAR ( CURDATE ()), ‘ - ‘ ,月(生日), ‘ - ‘ ,
IF (个月(生日) = 2 和 DAY (生日) = 29 ,
DAY( DATE_ADD ( CONCAT ( YEAR ( CURDATE ()), ‘-03-01‘ ), INTERVAL - 1 DAY )), DAY (出生日期))),‘%Y-%C-%E‘ )> CURDATE (),1 ,0 )AS年龄FROM用户;
+ ---- + --------- + ------------ + ------ +
| id | 名字 | 生日 | 年龄 |
+ ---- + --------- + ------------ + ------ +
| 1 | 弗兰 | 1967 - 10 - 31 | 43 |
| 2 | 比尔 | 1964年 - 05 - 07年| 47 |
| 3 | 吉米 | 1965 -04- 27 | 46 |
| 4 | Stacy | 2002 - 11 - 30 | 8 |
| 5 | 乔治 | 2007 - 10 - 25 | 3 |
| 6 | Leapie | 2008 -02- 29 | 3 |
| 7 | BadLeap | 0000-00-00 | 2011 |
+ ---- + --------- + ------------ + ------ +
7行中 集合 (0.00秒)
测试边缘情况
有点难以证明这对我们的边缘情况实际上是正确的,所以我们必须人为地用闰年代替curdate()来测试它,这很烦人但是必要。搜索和替换肯定有帮助。
SELECT *,YEAR (‘2011-02-28‘ ) -
YEAR (出生日期) -
IF ( STR_TO_DATE ( CONCAT ( YEAR (‘2011-02-28‘ ), ‘ - ‘,MONTH (出生日期),‘ - ‘,
IF (个月(生日) = 2和日(生日) = 29,
DAY ( DATE_ADD ( CONCAT( YEAR (‘2011-02-28‘ ), ‘-03-01‘ ),INTERVAL -1DAY )),
DAY (出生日期))
),‘%Y-%C-%E‘ ) > “2011-02 -28‘,1,0 )
AS年龄FROM用户,其中,ID = 6 ;
+ ---- + -------- + ------------ + ------ +
| id | 名字 | 生日 | 年龄 |
+ ---- + -------- + ------------ + ------ +
| 6 | Leapie | 2008 -02- 29 | 3 |
+ ---- + -------- + ------------ + ------ +
1行中 集合 (0.00秒)
这表明即使日期是非闰年的第28天,计算也正确地确定它应该被视为用户的生日。那么2012年是闰年呢?
SELECT *,YEAR (‘2012-02-28‘ ) -
YEAR (出生日期) -
IF ( STR_TO_DATE ( CONCAT ( YEAR (‘2012-02-28‘ ), ‘ - ‘,MONTH (出生日期),‘ - ‘,
IF (个月(生日) = 2和日(生日) = 29,
DAY ( DATE_ADD ( CONCAT( YEAR (‘2012-02-28‘ ), ‘-03-01‘ ),INTERVAL -1DAY )),
DAY (出生日期))
),‘%Y-%C-%E‘ ) > “2012-02 -28‘,1,0 )
AS年龄FROM用户,其中,ID = 6 ;
+ ---- + -------- + ------------ + ------ +
| id | 名字 | 生日 | 年龄 |
+ ---- + -------- + ------------ + ------ +
| 6 | Leapie | 2008 -02- 29 | 3 |
+ ---- + -------- + ------------ + ------ +
1行中 集合 (0.00秒)
它正确地确定‘Leapie‘仍然是3!第二天,Leapie享受闰年生日派对:
SELECT *,YEAR (‘2012-02-29‘ ) -
YEAR (出生日期) -
IF ( STR_TO_DATE ( CONCAT ( YEAR (‘2012-02-29‘ ), ‘ - ‘,MONTH (出生日期),‘ - ‘,
IF (个月(生日) = 2和日(生日) = 29,
DAY ( DATE_ADD ( CONCAT( YEAR (‘2012-02-29‘ ), ‘-03-01‘ ),INTERVAL -1DAY )),
DAY (出生日期))
),‘%Y-%C-%E‘ ) > “2012-02 -29‘,1,0 )
AS年龄FROM用户,其中,ID = 6 ;
+ ---- + -------- + ------------ + ------ +
| id | 名字 | 生日 | 年龄 |
+ ---- + -------- + ------------ + ------ +
| 6 | Leapie | 2008 -02- 29 | 4 |
+ ---- + -------- + ------------ + ------ +
1行中 集合 (0.00秒)
概要
MySQL可用于自动计算任何一天的人的准确年龄,即使对于在闰年2月29日出生的人也是如此。它很快,并且允许您利用MySQL日期类型和相关功能的强大功能,这样您就不必在服务器端代码中执行这些计算。这是查询一次:
SELECT *, YEAR ( CURDATE ()) -
YEAR (出生日期) -
IF ( STR_TO_DATE ( CONCAT ( YEAR ( CURDATE ()), ‘ - ‘ ,月(生日), ‘ - ‘ ,
IF (个月(生日) = 2 和 DAY (生日) = 29 ,
DAY (DATE_ADD ( CONCAT ( YEAR ( CURDATE ()), ‘-03-01‘ ), INTERVAL - 1 DAY )), DAY (出生日期))),‘%Y-%C-%E‘ )> CURDATE (),1 ,0 )AS年龄来自用户;