2010-03-28 96 views

回答

26

几个方法:

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 

希望这有助于你

+0

这就是优秀!非常感谢! – 2010-03-28 18:08:30

+0

很高兴帮助你。请将答案标记为已接受,以便其他人将来可以使用它:-) – 2010-03-28 18:10:31

+0

我很好奇:什么是0.25的? – ryanprayogo 2010-09-15 22:44:20

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

这个比接受的答案好。感谢发布! – 2016-01-11 18:59:52

+1

谢谢。我会用'year(x)'而不是'date_format(x,'%Y')'否则它很棒。 – Tobia 2016-07-15 10:09:30

19

布莱恩·丹尼的答案比接受的答案(我不知道更正确如何把它放在一个新的答案以外的地方;这是我第一次在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 

这实际上是“年度26(5月后的8日0 )”。请记住,对于日期时间类型,没有月份“0”,因此如果您想使用此格式来测量包含月份的日期时间间隔,则必须从月份中减去1。同样,与天组件,没有“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来弥补这一点。这由<比较的结果来处理,如果为true,则返回1,如果为false则返回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 

我希望这是更清晰的人的东西!

+1

最快的查询是什么@almaruf提供 – user1016265 2014-08-11 11:06:03

-2

这是我能想出迄今最简单的:

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

首先我们得到天的时间差,然后将其转换为年,然后FLOOR截断到数量的整数部分。

2

下面的sql对我来说工作得很好。总是使用带有dob的CURRENT_DATE来计算实际年龄。

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

假定给定的日期比当前日期时,

1.Find总无天的黑/白的当前日期和给定的日期。

- >DATEDIFF(NOW(),'1988-05-01')

2.Find无多年从没有计算天数。

- 由一个人>DATEDIFF(NOW(),'1988-05-01')/365.25

3,年龄应在完成没有几年。为了得到它,我们可以使用'floor'来计算no的年数。

- >FLOOR(DATEDIFF(NOW(),'1988-05-01')/365.25)

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

+0

恭喜,您刚刚复制了接受的答案,答案解释了为什么是错的。 – 2014-01-07 06:50:49

+0

请不要简单地发布代码。提供一些关于您的代码的解释或信息或用法。例如,请参阅[此答案](http://stackoverflow.com/a/16893057/756941)。 – NAZIK 2014-01-07 07:37:45

+0

感谢您的正确方向。 – 2014-01-07 08:50:08

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 
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; 
     SET l_age=CONCAT(YEARS, " Year ",MONTHS," Month ",DAYS," Days"); 
     RETURN(l_age); 
    END $$ 
DELIMITER ; 

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

为什么你的解决方案比最受赞誉的答案更好? – Marki555 2015-07-16 08:17:48

+0

谢谢,这给了我一个关于如何获得在我的应用程序中工作的年龄函数的想法。 – 2016-03-01 11:46:27

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

欢迎来到SO Ravi Shankar。无论此解决方案是否有效,最好为您的查询添加说明。这样,OP和其他读者将会更好地理解你想要达到的目标。 – dhh 2015-07-16 05:04:03

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

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