模拟数据如下,使用了数字辅助表创建数据.
http://blog.itpub.net/29254281/viewspace-1362897/
drop table if exists t;
create table t
(
id int primary key auto_increment,
birthday datetime
);
truncate table t;
insert into t(birthday)
select date_add('2011-12-15',interval id day) from nums limit 10;
insert into t(birthday)
select date_add('2010-2-26',interval id day) from nums limit 10;
insert into t(birthday)
select date_add('2008-2-26',interval id day) from nums limit 10;
今天是2014-12-19 ,t表模拟用户表,birthday模拟用户的出生日期

一开始我把问题想简单了,就想用year(now())-year(birthday)
但是当前日期在生日之前和生日之后,会有1年的误差.
最后处理的方式如下
select id,birthday,
case when
date_add(birthday,interval year(now())-year(birthday) year)>=now()
then
year(now())-year(birthday)-1
else
year(now())-year(birthday)
end age
from t;

如果需要计算用户的下次生日日期,参考MySQL技术内幕实现如下
1.先计算当前和出生日期的年份差值
2.出生日期加年份差值,和年份差值+1
3.如果生日是闰年29日,而当前年不是闰年,则判定生日为3月1日
可以制作一个函数
这个函数可以计算下次生日的日期.
http://blog.itpub.net/29254281/viewspace-1362897/
drop table if exists t;
create table t
(
id int primary key auto_increment,
birthday datetime
);
truncate table t;
insert into t(birthday)
select date_add('2011-12-15',interval id day) from nums limit 10;
insert into t(birthday)
select date_add('2010-2-26',interval id day) from nums limit 10;
insert into t(birthday)
select date_add('2008-2-26',interval id day) from nums limit 10;

一开始我把问题想简单了,就想用year(now())-year(birthday)
但是当前日期在生日之前和生日之后,会有1年的误差.
最后处理的方式如下
select id,birthday,
case when
date_add(birthday,interval year(now())-year(birthday) year)>=now()
then
year(now())-year(birthday)-1
else
year(now())-year(birthday)
end age
from t;

如果需要计算用户的下次生日日期,参考MySQL技术内幕实现如下
1.先计算当前和出生日期的年份差值
2.出生日期加年份差值,和年份差值+1
3.如果生日是闰年29日,而当前年不是闰年,则判定生日为3月1日
-
select id,birthday,if(cur>today,cur,next) as target
-
from
-
(
-
select id,birthday,today,
-
date_add(cur,interval
if(day(birthday)=29&&day(cur)=28,1,0) day) as cur,
-
date_add(next,interval
if(day(birthday)=29&&day(next)=28,1,0) day) as next
-
from
-
(
-
select id,birthday,today,
-
date_add(birthday,interval
diff year) as cur,
-
date_add(birthday,interval
diff+1 year) as next
-
from
-
(
-
select id,birthday,(year(now())-year(birthday)) as diff,now() as today from t
-
) a
-
) b
- ) c;
可以制作一个函数
-
SET GLOBAL log_bin_trust_function_creators = 1;
-
delimiter $$
-
create function age(birthday
datetime)
-
returns datetime
-
begin
-
return (
-
select if(cur>today,cur,next) as target
-
from
-
(
-
select birthday,today,
-
date_add(cur,interval
if(day(birthday)=29&&day(cur)=28,1,0) day) as cur,
-
date_add(next,interval
if(day(birthday)=29&&day(next)=28,1,0) day) as next
-
from
-
(
-
select birthday,today,
-
date_add(birthday,interval
diff year) as cur,
-
date_add(birthday,interval
diff+1 year) as next
-
from
-
(
-
select birthday,(year(now())-year(birthday)) as diff,now() as today from dual
-
) a
-
) b
-
) c
-
);
-
end$$
- delimiter ;
1048

被折叠的 条评论
为什么被折叠?



