在SQL Server數據庫中,我記錄了人們的出生日期。是否有一種直接的方法,只使用SQL來計算特定日期的人的年齡?在SQL中查找某人的年齡
使用DATEDIFF(YEAR,DateOfBirth,GETDATE())不起作用,因爲它只看到日期的年份部分。例如DATEDIFF(年,2007' 年12月'31,2008' 年01月)返回1
在SQL Server數據庫中,我記錄了人們的出生日期。是否有一種直接的方法,只使用SQL來計算特定日期的人的年齡?在SQL中查找某人的年齡
使用DATEDIFF(YEAR,DateOfBirth,GETDATE())不起作用,因爲它只看到日期的年份部分。例如DATEDIFF(年,2007' 年12月'31,2008' 年01月)返回1
看看這篇文章:How to calculate age of a person using SQL codes
以下是文章的代碼:
DECLARE @BirthDate DATETIME
DECLARE @CurrentDate DATETIME
SELECT @CurrentDate = '20070210', @BirthDate = '19790519'
SELECT DATEDIFF(YY, @BirthDate, @CurrentDate) - CASE WHEN((MONTH(@BirthDate)*100 + DAY(@BirthDate)) > (MONTH(@CurrentDate)*100 + DAY(@CurrentDate))) THEN 1 ELSE 0 END
還有另一種方法就是有點簡單:
Select CAST(DATEDIFF(hh, [birthdate], GETDATE())/8766 AS int) AS Age
因爲這裏的四捨五入是非常精細的,這是差不多完全準確。例外情況如此複雜以至於它們幾乎都是幽默的:如果我們A)在6:00 AM之前詢問年齡,B)在該人的生日和C)他們的生日在那之後,每四年返回的年齡將是一年太年輕2月28日。在我的情況下,這是一個完全可以接受的折中方案。
如果用一個靜態值替換GETDATE(),你會在午夜檢查後更頻繁地點擊異常。它看起來像從中午檢查而不是午夜會起作用。 – Guvante 2014-09-12 16:50:39
FWIW,年齡可以用簡單的方式來計算,而不訴諸黑客(不是有什麼不對的黑客!):
CREATE FUNCTION Age (@BirthDate DATETIME)
RETURNS INT
AS
BEGIN
DECLARE @AgeOnBirthdayThisYear INT
DECLARE @BirthdayThisYear DATETIME
SET @AgeOnBirthdayThisYear = DATEDIFF(year, @BirthDate, GETDATE())
SET @BirthdayThisYear = DATEADD(year, @AgeOnBirthdayThisYear, @BirthDate)
RETURN
@AgeOnBirthdayThisYear
- CASE WHEN @BirthdayThisYear > GETDATE() THEN 1 ELSE 0 END
END
該方案顯示在一個查詢如何不變量
SELECT DATEDIFF(YY, birthdate, GETDATE()) - CASE WHEN((MONTH(birthdate)*100 + DAY(birthdate)) > (MONTH(GETDATE())*100 + DAY(GETDATE()))) THEN 1 ELSE 0 END
這比提供的答案更簡潔和快一點,並且完全準確:
datediff(year,DateOfBirth,getdate()-datepart(dy,DateOfBirth)+1)
當GetDate()是出生日期時,此方法不起作用。這是一個例子,其中人應該是40歲,但它只返回39.`SELECT datediff(year,'1/29/1973',CAST('2013年1月29日'作爲日期時間) - datepart(dy,'1/29/1973'))` – 2013-01-29 20:39:18
我希望這個是完美的,只要你接受一個跳躍寶寶在2月29日或3月1日在非閏年接連的算法。 @DOB必須包含目前在幾個世紀內的日期,@AsOf必須包含一個類似的日期> = @DOB:
SET @Age = YEAR(@AsOf) - YEAR(@DOB) - 1
IF MONTH(@AsOf) * 100 + DAY(@AsOf) >= MONTH(@DOB) * 100 + DAY(@DOB)
SET @Age = @Age + 1
我真的非常感謝所有的測試和評論,因爲我還沒有找到一種方法還沒有打破它呢。
添加 - 2014年1月31日:此人似乎很好地工作過,即使在第一眼看上去過於簡陋:
SET @Age = FLOOR(DATEDIFF(dd,@DOB,@CompareDate)/365.25)
在函數彈出這些,這裏是一個測試腳本:
SELECT dbo.fnGetAge('2/27/2008', '2/27/2012')
SELECT dbo.fnGetAge('2/27/2008', '2/28/2012')
SELECT dbo.fnGetAge('2/27/2008', '2/29/2012')
SELECT dbo.fnGetAge('2/27/2008', '3/1/2012')
-- 4 4 4 4
SELECT dbo.fnGetAge('2/28/2008', '2/27/2012')
SELECT dbo.fnGetAge('2/28/2008', '2/28/2012')
SELECT dbo.fnGetAge('2/28/2008', '2/29/2012')
SELECT dbo.fnGetAge('2/28/2008', '3/1/2012')
-- 3 4 4 4
SELECT dbo.fnGetAge('2/29/2008', '2/27/2012')
SELECT dbo.fnGetAge('2/29/2008', '2/28/2012')
SELECT dbo.fnGetAge('2/29/2008', '2/29/2012')
SELECT dbo.fnGetAge('2/29/2008', '3/1/2012')
-- 3 3 4 4
SELECT dbo.fnGetAge('3/1/2008', '2/27/2012')
SELECT dbo.fnGetAge('3/1/2008', '2/28/2012')
SELECT dbo.fnGetAge('3/1/2008', '2/29/2012')
SELECT dbo.fnGetAge('3/1/2008', '3/1/2012')
-- 3 3 3 4
SELECT dbo.fnGetAge('3/1/2007', '2/27/2012')
SELECT dbo.fnGetAge('3/1/2007', '2/28/2012')
SELECT dbo.fnGetAge('3/1/2007', '2/29/2012')
SELECT dbo.fnGetAge('3/1/2007', '3/1/2012')
-- 4 4 4 5
SELECT dbo.fnGetAge('3/1/2007', '2/27/2013')
SELECT dbo.fnGetAge('3/1/2007', '2/28/2013')
SELECT dbo.fnGetAge('3/1/2007', '3/1/2013')
SELECT dbo.fnGetAge('2/27/2007', '2/28/2013')
SELECT dbo.fnGetAge('2/28/2007', '2/28/2014')
-- 5 5 6 6 7
乾杯
PS:你也許可以調整的2月29日的決定,是一個早一天如果你的船浮筒。
SELECT Pname, DOB, DATEDIFF(YEAR, DOB, GETDATE()) AS Age
FROM tablename
你真的可以把相關的代碼放在你的答案嗎?鏈接到其他網站可以(而且確實)中斷,所以如果鏈接不再有效,將來這個答案可能不會有用。 – 2008-11-12 12:24:58
@Tim C +1用於建議添加代碼,因爲該網站目前處於關閉狀態,並且此答案在僅有鏈接時將無法使用。 – 2011-11-01 22:42:16