模拟数据如下,使用了数字辅助表创建数据.
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 ;
