2012-05-08 31 views
15

我想要計算數據庫中某個人的年齡。
讓我們假設有這樣簡單的表:獲取MySQL中兩個日期之間的年差作爲整數

student(id, birth_date); 

其中ID是主鍵(真正的表是比較複雜的,但我已經簡化了的話)。
我想多少舊是一個人:

select id, datediff(curdate(),birth_date) 
from student 

但它在天返回結果,而不是years.I可以通過365將其劃分:

select id, datediff(curdate(),birth_date)/365 
from student 

但返回一個浮點值,我想要一個整數。
所以,我可以計算出年:

select id, year(curdate())-year(birth_date) 
from student 

但有一個問題:比如現在是五月,如果6月出生,1970年一個人的戰爭,他仍然具有31年,而不是32,但表達的回報32.
我不能出這個問題,有人可以幫我嗎?

回答

12
select id, floor(datediff(curdate(),birth_date)/365) 
from student 

怎麼樣地板的結果是一個整數?

+4

這十進制沒有考慮閏年考慮在內。漂移可以變得顯着。 '選擇樓層(datediff(「2017-03-19」,「1975-03-30」)/ 365);'說42. 42.這個人41天,11天休息。 – Schwern

+0

同意@Schwern – shrimpwagon

1

爲什麼不在第二種方法的輸出上使用MySQL的FLOOR()函數?任何分數將被丟棄,給你你想要的結果。

4

嘗試:

SELECT 
    DATE_FORMAT(FROM_DAYS(TO_DAYS(NOW())-TO_DAYS(birth_date)), '%Y')+0 
    AS age FROM student; 
+1

這可以簡化爲'SELECT YEAR(FROM_DAYS(TO_DAYS(NOW()) - TO_DAYS(「1975-04-20」)));'它正確地處理閏年。 – Schwern

0

你可以用它來獲取整數值。

select id, CAST(datediff(curdate(),birth_date)/365 as int) 
from student 

如果你想了解CONVERT()CAST()here is the link.

3

接受的答案几乎是正確的,但可能會導致錯誤的結果。

事實上,/ 365不考慮閏年,如果您比較同一天的日期爲&月份,則可能導致出現錯誤結果。

爲了更準確,你必須在平均天數在年內將其劃分爲4年,又名(365 * 4)+ 1(閏年每4年)=> 365.25

而且你會更準確:

select id, floor(datediff(curdate(),birth_date)/365.25) from student 

經過測試我的項目之一,它的工作。

+0

是不是過時(curdate(),birth_date被轉換爲浮點? –

+0

我不能肯定地說,但我測試了它,並且'/ 365'返回的結果不同於(/ 365.25) –

+0

是的,但我不應該使用像floor這樣的函數來削減結果嗎?我可能會得到一個非整數的年齡 –

0

我建議這樣的:

DATE_FORMAT(NOW(),"%Y") 
    -DATE_FORMAT(BirthDate,'%Y') 
    -(
    IF(
     DATE_FORMAT(NOW(),"%m-%d") < DATE_FORMAT(BrthDate,'%m-%d'), 
     1, 
     0 
    ) 
    ) as Age 

這應該與飛躍年工作非常好;-)

44

對於任何人誰碰到這個涉及:

另一種方法可以做到這一點是:

SELECT TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) AS difference FROM student 

對於月份差異,請用替換,以及天替換YEARDAY

希望幫助!

+2

同上coolscitist - 這看起來是最簡單,最優雅的答案。 – Fred

+4

請將此標記爲正確答案,其他人不是excact! – Tobias

+0

同意。最準確。 – shrimpwagon

0

這個工程,即使考慮到閏年!

select floor((cast(date_format('2016-02-29','%Y%m%d') as int) - cast(date_format('1966-03-01','%Y%m%d') as int)/10000); 

只是一定要保持floor(),因爲不需要

相關問題