如何从 MySQL 的 DOB 字段中获取年龄?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2533890/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 15:38:57  来源:igfitidea点击:

How to get an age from a D.O.B field in MySQL?

mysqlselectdate

提问by aadersh patel

I need to calculate the age of a "customer" from their date of birth.

我需要从他们的出生日期计算“客户”的年龄。

I have tried to use the following:

我尝试使用以下内容:

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

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

But it does not seem to work.

但它似乎不起作用。

Any ideas? I KNOW it is going to be something simple!

有任何想法吗?我知道这会很简单!

Thanks

谢谢

回答by Bryan Denny

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

回答by almaruf

Use Mysql recommended :

推荐使用Mysql:

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

Usage in a query :

查询中的用法:

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

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

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

回答by Marcos Placona

A few ways:

几种方式:

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

Hope this helps you

希望这对你有帮助

回答by tokes

Bryan Denny's answer is more correct than the accepted answer(I wasn't sure how to put this in somewhere other than a new answer; this is my first time on StackOverflow).

Bryan Denny 的答案比接受的答案更正确(我不确定如何将它放在新答案以外的其他地方;这是我第一次使用 StackOverflow)。

Marcos' first attempt:

马科斯的第一次尝试:

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

will firstly yield a negative result (the arguments to DATEDIFF are in the wrong order), and secondly will produce inaccurate results for some dates, e.g.:

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

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

produces the result:

产生结果:

25.9986

You can't just simply always round up, because that will also cause inaccurate results for other inputs.

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

Marcos' second attempt:

马科斯的第二次尝试:

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

Again, the arguments are in the wrong order, except this time instead of just producing a negative number, the FROM_DAYS() function does not work correctly with negative input. Secondly, if we look closer at the output of the FROM_DAYS() function:

同样,参数的顺序是错误的,除了这次不是只产生负数,FROM_DAYS() 函数在负输入时不能正常工作。其次,如果我们仔细观察 FROM_DAYS() 函数的输出:

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

The result of the above is:

上面的结果是:

0026-05-08

which is literally "8th of May, Year 26 (after 0)". Keep in mind that for datetime types, there is no month "0", so if you wanted to use this format to measure a date interval with months included, you'd have to subtract 1 from the month. Similarly, with the day component, there is no "0", so the result is not what you'd expect for this problem when the date happens to be the birthday:

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

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

produces:

产生:

0025-12-31

which if we shorten using Marcos' date formatting gives us "25", which is an incorrect calculation of age.

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

Bryan Denny's answer is correct in all these edge cases. His formula is quite clever:

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

The first part calculates the difference in years between the two dates. So if we take "2010" and "1984" as reference and birthdate respectively, the result is "26". The second part then calculates essentially "Does the birthdate month and day occur after the reference month and day?" If it does, it "hasn't happened yet", so we need to subtract an additional 1 from the year difference to make up for this. This is taken care of by the result of the < comparison, which returns 1 if true and 0 if false.

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

So, full examples:

所以,完整的例子:

1)

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)

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

I hope this makes things clearer for people!

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

回答by Ipsita Rout

The below sql works fine for me. Always use CURRENT_DATEwith dob to calculate the actual age .

下面的 sql 对我来说很好用。始终CURRENT_DATE与 dob 一起使用来计算实际年龄。

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

回答by Sapna Bhayal

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

I found some useful queries from below article for calculating age :- http://www.gizmola.com/blog/archives/archives/107-Calculate-a-persons-age-in-a-MySQL-query.html

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

回答by Ali A. Dhillon

If you want years, months and days like "26 years 4 months and 27 days" then following is the age function for you:

如果您想要像“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;

We are calculating the age from current date so I set today to curdate(). Now we are getting our years, months and days as following.

我们正在计算当前日期的年龄,所以我今天设置为 curdate()。现在我们的年、月和日如下。

  1. years:We get the difference in years from today to date of birth.

  2. months:First we subtract the years from the today so that we only get months that are extra from the years and then find the difference in months from date of birth. Here "years" is the variable and "year" is interval type.

  3. days:And here we subtract years and months that we have already calculated from today which is current date then find the diff in days from birth. Here "months" is the variable and "month" is interval type.
  1. 年:我们得到从今天到出生日期的年数差异。

  2. 月数:首先我们从今天减去年数,这样我们只得到年数中额外的月数,然后找出从出生日期算起的月数差异。这里“years”是变量,“year”是区间类型。

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

You can use datetime instead of date as argument if you want also you can format the return values as you like.

如果需要,您可以使用 datetime 而不是 date 作为参数,也可以根据需要格式化返回值。

回答by S.Mishra

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

Above MySQL query has been tested and verified. It will give you exact age in years. I have taken this idea from Marcos answer and switched DATEDIFF() parameters.

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

回答by user1218947

Depends on your needs- int and float functions provided.
- Your business rules may differ so adjust accordingly

取决于您的需要- 提供 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

回答by Ravi Shankar

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));