2011-04-24 44 views
45

如果我在表格中以dd-mm-yyyy的形式存储了一个人的出生日期,并且从当前日期中减去它,那么返回的日期格式是什么?在MySQL中计算年龄(InnoDb)

如何使用此返回的格式来计算某人的年龄?

+5

这是什么RDBMS?日期函数不是那么标准化的AFAIK。你的意思是以'dd-mm-yyyy'的格式存储了什么?如果它是'date'数据类型,它可能会以数字格式存储(例如,从某个起点开始的几天内的整数) – 2011-04-24 21:47:21

+0

您好我正在使用InnoDb和phpMyAdmin ....它存储为日期变量。我认为它是yyyymmdd - 错误高于 – user559142 2011-04-24 22:06:42

+0

如果数据存储为DATE或DATETIME数据类型,则它以二进制值形式存储,而不是以任何特定的人类可读格式存储。格式化仅在输出到文本时发生,并且取决于操作系统区域设置等因素或由您提供的明确格式说明。尽可能使用_expect_ DATE和DATETIME类型值处理DATE和DATETIME值。那么你不会遇到日期格式的问题。您可能仍然需要与时区混淆,但至少您的calc只是有点偏离而不是完全破碎。 – gwideman 2014-07-29 09:14:16

回答

46

如果该值被存储为DATETIME数据类型:

SELECT YEAR(CURRENT_TIMESTAMP) - YEAR(dob) - (RIGHT(CURRENT_TIMESTAMP, 5) < RIGHT(dob, 5)) as age 
    FROM YOUR_TABLE 

不太精确的,当你考虑闰年:

SELECT DATEDIFF(CURRENT_DATE, STR_TO_DATE(t.birthday, '%d-%m-%Y'))/365 AS ageInYears 
    FROM YOUR_TABLE t 
+0

... /365.25来处理闰年。但在2000年,跳过了闰年。但是,如果你能忍受1天的错误。 – 2011-04-24 22:36:02

+22

官方的MySQL文档有一个正确的答案:http://dev.mysql.com/doc/refman/5.0/en/date-calculations.html – mojuba 2013-01-23 01:35:29

+0

@mojuba:这是一种不同的方式,不一定是正确的 - 我如果它不令人满意,不要认为OP会将此标记为答案。鉴于此,如果你倒退你的失望,我会很感激,而且问题已近两年。 – 2013-01-23 04:44:43

4
select floor(datediff (now(), birthday)/365) as age 
+0

对不起。只是修好了。他可以根据需要使用地板或小屋。 – lobster1234 2011-04-24 22:22:07

+0

由于闰年,在某些情况下会出错。 – Sklivvz 2011-04-24 22:26:25

+1

是的,如果那是OP想要的,它不会为那个准确度工作。然而,你需要365闰年才能让1岁的年龄有所不同,不是吗? – lobster1234 2011-04-24 22:28:17

10
select *,year(curdate())-year(dob) - (right(curdate(),5) < right(dob,5)) as age from your_table 
这样你考虑偶数月和出生日期,以便有更准确的年龄计算

+0

哇这个工程很棒 - 你能向我解释什么 - (右(curdate(),5)<右(dob,5))部分呢? – user559142 2011-04-24 22:26:39

+0

是的。正确(...,5)从当前日期和出生日期中提取mm-dd。您将它们与“<”符号进行比较,如果出生日期的日期和月份小于当前日期,则返回0,否则返回1。所以你可以从年差中减去它(0或1)。 – 2011-04-24 22:31:50

+1

我会做一个大的修改。在我的MySQL权利(dob,5)返回日期的小时 - 分钟部分。这可以通过使用'year(curdate()) - year(dob) - (dayofyear(curdate()) regilero 2013-03-01 11:52:12

1

试试这个:

SET @birthday = CAST('1980-05-01' AS DATE); 
SET @today = CURRENT_DATE(); 

SELECT YEAR(@today) - YEAR(@birthday) - 
    (CASE WHEN 
    MONTH(@birthday) > MONTH(@today) OR 
    (MONTH(@birthday) = MONTH(@today) AND DAY(@birthday) > DAY(@today)) 
     THEN 1 
     ELSE 0 
    END); 

它返回年 - 出生年(生日之后这个人多大年纪),并根据这个人是否有ha来调整今年的生日。

它不会受到这里介绍的其他方法的舍入误差。

自由地从here

0

适应这是如何计算在MySQL中年龄:

select 
    date_format(now(), '%Y') - date_format(date_of_birth, '%Y') - 
    (date_format(now(), '00-%m-%d') < date_format(date_of_birth, '00-%m-%d')) 
as age from table 
+1

downvote的任何理由? – 2016-04-07 22:50:11

0

你可以让一个函数来做到这一点:

drop function if exists getIdade; 

delimiter | 

create function getIdade(data_nascimento datetime) 
returns int 
begin 
    declare idade int; 
    declare ano_atual int; 
    declare mes_atual int; 
    declare dia_atual int; 
    declare ano int; 
    declare mes int; 
    declare dia int; 

    set ano_atual = year(curdate()); 
    set mes_atual = month(curdate()); 
    set dia_atual = day(curdate()); 

    set ano = year(data_nascimento); 
    set mes = month(data_nascimento); 
    set dia = day(data_nascimento); 

    set idade = ano_atual - ano; 

    if(mes > mes_atual) then 
      set idade = idade - 1; 
    end if; 

    if(mes = mes_atual and dia > dia_atual) then 
      set idade = idade - 1; 
    end if; 

    return idade; 
end| 

delimiter ; 

现在,你可以从日期得到年龄:

select getIdade('1983-09-16'); 

如果日期是格式Y-M-d H:I:S,你可以这样做:

select getIdade(substring_index('1983-09-16 23:43:01', ' ', 1)); 

你可以在任何地方重复使用此功能;)

+2

绝对要走的路,如果你是由代码行支付:-)。 – gwideman 2014-07-29 09:00:17

0

我更喜欢用一个函数这种方式。

DELIMITER $$ DROP FUNCTION IF EXISTS `db`.`F_AGE` $$ 
    CREATE FUNCTION `F_AGE`(in_dob datetime) RETURNS int(11) 
     NO SQL 
    BEGIN 
     DECLARE l_age INT; 
     IF DATE_FORMAT(NOW(),'00-%m-%d') >= DATE_FORMAT(in_dob,'00-%m-%d') THEN 
      -- This person has had a birthday this year 
      SET l_age=DATE_FORMAT(NOW(),'%Y')-DATE_FORMAT(in_dob,'%Y'); 
     ELSE 
      -- Yet to have a birthday this year 
      SET l_age=DATE_FORMAT(NOW(),'%Y')-DATE_FORMAT(in_dob,'%Y')-1; 
     END IF; 
     RETURN(l_age); 
    END $$ 

    DELIMITER ; 

现在使用

SELECT F_AGE('1979-02-11') AS AGE; 

OR

SELECT F_AGE(date) AS age FROM table; 
2

简单:

DATE_FORMAT(FROM_DAYS(TO_DAYS(NOW())-TO_DAYS(`birthDate`)), '%Y')+0 AS age 
+0

与TIMESTAMPDIFF()相比并不简单() – gwideman 2014-07-29 08:56:47

0

由于问题被标记为mysql,我有以下的实现,它的工作原理对我来说d我希望类似的替代方案可以用于其他RDBMS。这里的SQL:

select YEAR(now()) - YEAR(dob) - (DAYOFYEAR(now()) < DAYOFYEAR(dob)) as age 
from table 
where ... 
162

可以使用TIMESTAMPDIFF(unit, datetime_expr1, datetime_expr2)功能:

SELECT TIMESTAMPDIFF(YEAR, '1970-02-01', CURDATE()) AS age 

Demo

+6

小而精确且简单的解决方案。 – 2014-03-25 00:10:37

+3

这似乎是明显的赢家。我不知道为什么有人会用繁琐易用的方法将日期转换为字符串等。 – gwideman 2014-07-29 08:56:05

+0

哇解决方案!感谢分享 – Xiabili 2015-02-17 13:43:11

6
SELECT TIMESTAMPDIFF (YEAR, YOUR_COLUMN, CURDATE()) FROM YOUR_TABLE AS AGE 

Click for demo ..

素雅..

0

根本就

SELECT birthdate, (YEAR(CURDATE())-YEAR(birthdate)) AS age FROM `member` 

生日是从出生日期字段保留字段名的出生名 取CURDATE()逐年转年()命令 减去与YEAR()

0

在两个simples的方式来做到这一点:

1-

select("users.birthdate", 
      DB::raw("FLOOR(DATEDIFF(CURRENT_DATE, STR_TO_DATE(users.birthdate, '%Y-%m-%d'))/365) AS age_way_one"), 

2-

select("users.birthdate",DB::raw("(YEAR(CURDATE())-YEAR(users.birthdate)) AS age_way_two"))