如何从MySQL中的D.O.B字段中获取年龄?

时间:2010-03-28 17:56:35

标签: mysql select date

我需要从出生日期开始计算“顾客”的年龄。

我试过使用以下内容:

  

DATEDIFF(year,customer.dob,“2010-01-01”);

但它似乎不起作用。

有什么想法吗?我知道它会变得简单!

由于

14 个答案:

答案 0 :(得分:47)

SELECT DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age

答案 1 :(得分:27)

有几种方法:

select DATEDIFF(customer.dob, '2010-01-01') / 365.25 as age

SELECT DATE_FORMAT(FROM_DAYS(DATEDIFF(customer.dob,'2010-01-01')), ‘%Y’)+0 AS age

希望这有助于你

答案 2 :(得分:26)

使用推荐的Mysql:

TIMESTAMPDIFF(YEAR, dob, CURDATE()) AS age;

查询中的用法:

SELECT name, dob, TIMESTAMPDIFF(YEAR, dob, CURDATE()) AS age FROM pet;

参考:http://dev.mysql.com/doc/refman/5.0/en/date-calculations.html

答案 3 :(得分:19)

Bryan Denny的答案比接受的答案更正确(我不知道如何把它放在除了新答案之外的某个地方;这是我第一次使用StackOverflow)。

马科斯的第一次尝试:

select DATEDIFF(customer.dob, '2010-01-01') / 365.25 as age

首先会产生否定结果(DATEDIFF的参数顺序错误),其次会在某些日期产生不准确的结果,例如:

SELECT DATEDIFF('2010-05-11','1984-05-11') / 365.25 AS age

产生结果:

25.9986

您不能简单地总是向上舍入,因为这也会导致其他输入的结果不准确。

马科斯的第二次尝试:

SELECT DATE_FORMAT(FROM_DAYS(DATEDIFF(customer.dob,'2010-01-01')), ‘%Y’)+0 AS age

同样,参数的顺序是错误的,除了这次,而不是只生成一个负数,FROM_DAYS()函数不能正确地使用负输入。其次,如果我们仔细观察FROM_DAYS()函数的输出:

select from_days(datediff('2010-09-16','1984-05-11'));

以上结果是:

0026-05-08

字面意思是“5月8日,26年(0之后)”。请记住,对于日期时间类型,没有月份“0”,因此如果您想使用此格式来测量包含月份的日期间隔,则必须从月中减去1。类似地,对于day组件,没有“0”,因此当日期恰好是生日时,结果不是您对此问题的期望:

select from_days(datediff('2010-05-11','1984-05-11'));

产生

0025-12-31

如果我们缩短使用Marcos的日期格式会给我们“25”,这是一个不正确的年龄计算。

Bryan Denny在所有这些边缘案例中的答案是正确的。他的公式非常聪明:

SELECT DATE_FORMAT(reference, '%Y') - DATE_FORMAT(birthdate, '%Y') - (DATE_FORMAT(reference, '00-%m-%d') < DATE_FORMAT(birthdate, '00-%m-%d')) AS age

第一部分计算两个日期之间的年份差异。因此,如果我们分别以“2010”和“1984”作为参考和生日,结果为“26”。然后,第二部分基本上计算“出生日期月和日是否出现在参考月和日之后?”如果确实如此,它“还没有发生”,所以我们需要从年份中减去额外的1来弥补这一点。这由&lt;的结果来处理。比较,如果为真则返回1,如果为假则返回0。

所以,完整的例子:

1)

Reference date: 2010-05-10;
Birthdate: 1984-05-11

Year difference = 2010 - 1984 = 26
Month and day comparison: May 10th < May 11th? Yes => subtract an additional year
Calculated age: 25 years

2)

Reference date: 2010-05-11;
Birthdate: 1984-05-11

Year difference = 2010 - 1984 = 26
Month and day comparison: May 11th < May 11th? No => subtract 0
Calculated age: 26 years

我希望这能让人们更加清楚!

答案 4 :(得分:2)

以下sql对我来说很好。始终使用带有dob的CURRENT_DATE来计算实际年龄。

SELECT 
    DATE_FORMAT(
        FROM_DAYS(
            DATEDIFF(CURRENT_DATE, dob)
        ),
        '%y Years %m Months %d Days'
    ) AS age 
FROM 
    users

答案 5 :(得分:2)

简单的方法:

timestampdiff(YEAR,birth_date,now())AS年龄

答案 6 :(得分:1)

SELECT *, YEAR(CURDATE()) - YEAR(birthdate) AS age FROM user;

我从下面的文章中找到了一些有用的查询来计算年龄:- http://www.gizmola.com/blog/archives/archives/107-Calculate-a-persons-age-in-a-MySQL-query.html

答案 7 :(得分:0)

取决于您的需求   - 提供int和float函数   - 您的业务规则可能会有所不同,因此需要相应调整

DROP FUNCTION IF EXISTS `age`; 
CREATE FUNCTION `age` (
  `pdate_begin` DATE,
  `pdate_end` DATETIME
) RETURNS INT(11) UNSIGNED   
COMMENT 'Calc age between two dates as INT' 
DETERMINISTIC NO SQL SQL SECURITY DEFINER
RETURN floor(datediff(pdate_end, pdate_begin) / 365.25) ;

DROP FUNCTION IF EXISTS `age_strict`; 
CREATE FUNCTION `age_strict` (
  `pdate_begin` DATE,
  `pdate_end` DATETIME
) RETURNS decimal(10,4)
COMMENT 'Calc age between two dates as DECIMAL .4' 
DETERMINISTIC NO SQL SQL SECURITY DEFINER
RETURN round(datediff(pdate_end, pdate_begin) / 365.25, 4) ;

-- test harness
select 
    age(dob, now())        as age_int,
    age_strict(dob, now()) as age_dec
    from customer 
    where dob is not null 
    order by age(dob,now()) desc;

-- test results
dob,                  age_int,            age_dec
1981-01-01 00:00:00        33             33.9713
1987-01-09 00:00:00        27             27.9507
2014-11-25 00:00:00         0              0.0739

答案 8 :(得分:0)

DELIMITER $$ DROP FUNCTION IF EXISTS `test`.`_AGE` $$
    CREATE FUNCTION `_AGE`(in_dob datetime) RETURNS VARCHAR(100)
        NO SQL
    BEGIN
       DECLARE l_age VARCHAR(100);
       DECLARE YEARS INT(11);
       DECLARE MONTHS INT(11);
       DECLARE DAYS INT(11);
       DECLARE DIFFS FLOAT;


       SET DIFFS=DATEDIFF(CURRENT_DATE(),in_dob) /365.25;
       SET YEARS=FLOOR(DIFFS) ;
       SET MONTHS=FLOOR((DIFFS - YEARS)*365.25/30.4375) MOD 12;
       SET DIFFS=((DIFFS - YEARS)*365.25/30.4375);
       SET DAYS=CEIL(((DIFFS-MONTHS)*30.4375)) MOD 31;
       SET l_age=CONCAT(YEARS, " Year ",MONTHS," Month ",DAYS," Days");
       RETURN(l_age);
    END $$
DELIMITER ;

SELECT _Age(CAST('1980-07-16' AS DATE));

答案 9 :(得分:0)

DATE_FORMAT(FROM_DAYS(DATEDIFF(CURDATE(),'1869-10-02')), '%Y')+0 AS age;

以上MySQL查询已经过测试和验证。它会给你几年的确切年龄。我从Marcos的回答中获取了这个想法并切换了DATEDIFF()参数。

答案 10 :(得分:0)

如果您想要年,月和日,例如“ 26年4个月零27天”,那么以下是您的年龄函数:

delimiter $$

create function age(dob date)
returns varchar(30)
deterministic
begin
declare years int default 0;
declare months int default 0;
declare days int default 0;
declare today date default curdate();

set years = timestampdiff(year, dob, today);    
set months = timestampdiff(month, dob, today - interval years year);    
set days = timestampdiff(day, dob, today - interval years year - interval months month);

return (concat(years, ' years ', months,' months and ', days,' days'));

end$$

delimiter;

我们正在计算从当前日期开始的年龄,因此我今天将其设置为curdate()。 现在我们得到的年,月和日如下。

  1. 年龄:我们得出从今天到出生日期的年数差异。

  2. 月::首先,我们从今天减去年份,以便仅 得到几年中多余的月份,然后找出差异 从出生日期算起的几个月。这里的“年”是变量,“年”是区间类型。

  3. 天:在这里,我们减去年份和月份 已经从今天算起,这是当前日期,然后找到 出生后几天的差异。这里“ months”是变量,“ month”是间隔类型。

如果需要,可以使用datetime代替date作为参数,也可以根据需要设置返回值的格式。

答案 11 :(得分:-1)

DELIMITER $$ DROP FUNCTION IF EXISTS `test`.`__AGE` $$
    CREATE FUNCTION `_AGE`(in_dob datetime) RETURNS VARCHAR(100)
        NO SQL
    BEGIN
       DECLARE l_age VARCHAR(100);
       DECLARE YEARS INT(11);
       DECLARE MONTHS INT(11);
       DECLARE DAYS INT(11);
       DECLARE DIFFS FLOAT;


       SET DIFFS=DATEDIFF(CURRENT_DATE(),in_dob) /365.25;
       SET YEARS=FLOOR(DIFFS) ;
       SET MONTHS=FLOOR((DIFFS - YEARS)*365.25/30.4375) MOD 12;
       SET DIFFS=((DIFFS - YEARS)*365.25/30.4375);
       SET DAYS=CEIL(((DIFFS-MONTHS)*30.4375)) MOD 31;
       RETURN(CONCAT(YEARS, " Year ",MONTHS," Month ",DAYS," Days"));

    END $$
DELIMITER ;

SELECT __Age(CAST('1980-07-16' AS DATE));

答案 12 :(得分:-2)

到目前为止,这是我能想到的最简单的方法:

SELECT FLOOR(ABS(DATEDIFF(d, CURRENT_TIMESTAMP, dob))/365.25) AS age

首先我们得到日期差异,然后将其转换为年,然后FLOOR截断为数字的整数部分。

答案 13 :(得分:-2)

假设给定日期大于当前日期,

1.找出当前日期和给定日期的总天数。

- &GT; DATEDIFF(NOW(),'1988-05-01')

2.从计算的天数中找出年数。

- &GT; DATEDIFF(NOW(),'1988-05-01')/365.25

3.年龄应该是一个人完成的年数。为了得到它,我们可以使用'floor'来计算年数。

- &GT; FLOOR(DATEDIFF(NOW(),'1988-05-01')/365.25)

示例:SELECT FLOOR(DATEDIFF(NOW(),'1988-05-01')/365.25) AS age;