2010-03-28 58 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()參數。