생년월일 (현재 nvarchar (25))과 함께 사람들을 나열한 표가 있습니다.
날짜로 변환 한 다음 나이를 몇 년으로 계산할 수 있습니까?
내 데이터는 다음과 같습니다
ID Name DOB
1 John 1992-01-09 00:00:00
2 Sally 1959-05-20 00:00:00
나는보고 싶다 :
ID Name AGE DOB
1 John 17 1992-01-09 00:00:00
2 Sally 50 1959-05-20 00:00:00
답변
윤년 / 일 및 다음 방법에 문제가 있습니다. 아래 업데이트를 참조하십시오.
이 시도:
DECLARE @dob datetime SET @dob='1992-01-09 00:00:00' SELECT DATEDIFF(hour,@dob,GETDATE())/8766.0 AS AgeYearsDecimal ,CONVERT(int,ROUND(DATEDIFF(hour,@dob,GETDATE())/8766.0,0)) AS AgeYearsIntRound ,DATEDIFF(hour,@dob,GETDATE())/8766 AS AgeYearsIntTrunc
산출:
AgeYearsDecimal AgeYearsIntRound AgeYearsIntTrunc --------------------------------------- ---------------- ---------------- 17.767054 18 17 (1 row(s) affected)
여기에 업데이트 더 정확한 방법이 있습니다 :
INT 년 동안 가장 좋은 방법
DECLARE @Now datetime, @Dob datetime
SELECT @Now='1990-05-05', @Dob='1980-05-05' --results in 10
--SELECT @Now='1990-05-04', @Dob='1980-05-05' --results in 9
--SELECT @Now='1989-05-06', @Dob='1980-05-05' --results in 9
--SELECT @Now='1990-05-06', @Dob='1980-05-05' --results in 10
--SELECT @Now='1990-12-06', @Dob='1980-05-05' --results in 10
--SELECT @Now='1991-05-04', @Dob='1980-05-05' --results in 10
SELECT
(CONVERT(int,CONVERT(char(8),@Now,112))-CONVERT(char(8),@Dob,112))/10000 AS AgeIntYears
위의 값 10000
을로 변경하고 10000.0
소수를 얻을 수는 있지만 아래 방법만큼 정확하지는 않습니다.
십년 동안 가장 좋은 방법
DECLARE @Now datetime, @Dob datetime
SELECT @Now='1990-05-05', @Dob='1980-05-05' --results in 10.000000000000
--SELECT @Now='1990-05-04', @Dob='1980-05-05' --results in 9.997260273973
--SELECT @Now='1989-05-06', @Dob='1980-05-05' --results in 9.002739726027
--SELECT @Now='1990-05-06', @Dob='1980-05-05' --results in 10.002739726027
--SELECT @Now='1990-12-06', @Dob='1980-05-05' --results in 10.589041095890
--SELECT @Now='1991-05-04', @Dob='1980-05-05' --results in 10.997260273973
SELECT 1.0* DateDiff(yy,@Dob,@Now)
+CASE
WHEN @Now >= DATEFROMPARTS(DATEPART(yyyy,@Now),DATEPART(m,@Dob),DATEPART(d,@Dob)) THEN --birthday has happened for the @now year, so add some portion onto the year difference
( 1.0 --force automatic conversions from int to decimal
* DATEDIFF(day,DATEFROMPARTS(DATEPART(yyyy,@Now),DATEPART(m,@Dob),DATEPART(d,@Dob)),@Now) --number of days difference between the @Now year birthday and the @Now day
/ DATEDIFF(day,DATEFROMPARTS(DATEPART(yyyy,@Now),1,1),DATEFROMPARTS(DATEPART(yyyy,@Now)+1,1,1)) --number of days in the @Now year
)
ELSE --birthday has not been reached for the last year, so remove some portion of the year difference
-1 --remove this fractional difference onto the age
* ( -1.0 --force automatic conversions from int to decimal
* DATEDIFF(day,DATEFROMPARTS(DATEPART(yyyy,@Now),DATEPART(m,@Dob),DATEPART(d,@Dob)),@Now) --number of days difference between the @Now year birthday and the @Now day
/ DATEDIFF(day,DATEFROMPARTS(DATEPART(yyyy,@Now),1,1),DATEFROMPARTS(DATEPART(yyyy,@Now)+1,1,1)) --number of days in the @Now year
)
END AS AgeYearsDecimal
답변
이걸 버려야 해. 당신이 경우 변환 숫자로 112 스타일 (YYYYMMDD)를 사용하여 날짜를이 같은 계산을 사용할 수 있습니다 …
(yyyyMMdd-yyyyMMdd) / 10000 = 연도 차이
declare @as_of datetime, @bday datetime;
select @as_of = '2009/10/15', @bday = '1980/4/20'
select
Convert(Char(8),@as_of,112),
Convert(Char(8),@bday,112),
0 + Convert(Char(8),@as_of,112) - Convert(Char(8),@bday,112),
(0 + Convert(Char(8),@as_of,112) - Convert(Char(8),@bday,112)) / 10000
산출
20091015 19800420 290595 29
답변
거의 10 년 동안 프로덕션 코드에서이 쿼리를 사용했습니다.
SELECT FLOOR((CAST (GetDate() AS INTEGER) - CAST(Date_of_birth AS INTEGER)) / 365.25) AS Age
답변
위의 많은 솔루션이 잘못되었습니다 .DateDiff (yy, @ Dob, @PassedDate)는 두 날짜의 월과 일을 고려하지 않습니다. 또한 다트 부품을 가져 와서 제대로 주문한 경우에만 비교하십시오.
다음 코드는 작동하며 매우 간단합니다.
create function [dbo].[AgeAtDate](
@DOB datetime,
@PassedDate datetime
)
returns int
with SCHEMABINDING
as
begin
declare @iMonthDayDob int
declare @iMonthDayPassedDate int
select @iMonthDayDob = CAST(datepart (mm,@DOB) * 100 + datepart (dd,@DOB) AS int)
select @iMonthDayPassedDate = CAST(datepart (mm,@PassedDate) * 100 + datepart (dd,@PassedDate) AS int)
return DateDiff(yy,@DOB, @PassedDate)
- CASE WHEN @iMonthDayDob <= @iMonthDayPassedDate
THEN 0
ELSE 1
END
End
답변
datediff 명령이 반올림되는 방식을 고려해야합니다.
SELECT CASE WHEN dateadd(year, datediff (year, DOB, getdate()), DOB) > getdate()
THEN datediff(year, DOB, getdate()) - 1
ELSE datediff(year, DOB, getdate())
END as Age
FROM <table>
2020 년 2 월 29 일에 태어난 사람은 2021 년 3 월 01 일 대신 2021 년 2 월 28 일에 1 세가 된 것으로 간주됩니다.
답변
편집 :이 답변이 잘못되었습니다. 나는 여기 dayofyear
에 추가 유혹 과 함께 사용하려는 유혹을 가진 사람들에게 경고로 남겨 둡니다 .
나처럼 분수 일로 나누거나 반올림 / 윤년 오류를 위험으로 나누고 싶지 않다면 https://stackoverflow.com/a/1572257/489865 위의 게시물에 @Bacon Bits 의견을 박수로 보냅니다 .
우리가 인간 연령에 대해 이야기하고 있다면, 인간이 연령을 계산하는 방식으로 계산해야합니다. 지구가 얼마나 빨리 움직이는 지, 달력과 관련된 모든 것과는 아무런 관련이 없습니다. 생년월일과 동일한 월과 일이 경과 할 때마다 나이가 1 씩 증가합니다. 이는 다음과 같이 인간이 “나이”라고 말할 때의 의미를 반영하기 때문에 가장 정확합니다.
그는 다음을 제공합니다.
DATEDIFF(yy, @date, GETDATE()) -
CASE WHEN (MONTH(@date) > MONTH(GETDATE())) OR (MONTH(@date) = MONTH(GETDATE()) AND DAY(@date) > DAY(GETDATE()))
THEN 1 ELSE 0 END
여기에는 월 & 일을 비교하는 몇 가지 제안이 있습니다 (일부는 잘못하여 OR
여기를 올바르게 허용하지 못합니다!). 그러나 아무도 제공하지 않았습니다 dayofyear
. 그렇게 간단하고 훨씬 짧은 것 같습니다. 나는 제안한다 :
DATEDIFF(year, @date, GETDATE()) -
CASE WHEN DATEPART(dayofyear, @date) > DATEPART(dayofyear, GETDATE()) THEN 1 ELSE 0 END
[참고 : SQL BOL / MSDN의 어디에도 DATEPART(dayofyear, ...)
실제로 반환되는 문서는 없습니다! 1-366 범위의 숫자 인 것으로 알고 있습니다. 가장 중요한 것은 & 로 로케일에 따라 바뀌지 않는다는 것 입니다.]DATEPART(weekday, ...)
SET DATEFIRST
편집 : 왜 dayofyear
잘못 : 출산 / 날짜가 아닌 윤년 2 월 이후 시작하면 현재 / 종료 날짜가 윤년 인 경우 사용자로서 @AeroX이 예는, 나이가 일일 초 증가, 댓글을 달았습니다 '2015-05-26'
, '2016-05-25'
을 제공합니다 나이가 여전히 0이어야하는 1 세 dayofyear
. 다른 연도를 비교하는 것은 분명히 위험합니다. 따라서를 사용 MONTH()
하고 DAY()
결국 필요합니다.
답변
항상 정확한 나이를 제공하는 간단한 대답이 없기 때문에 여기에 내가 생각해 낸 것이 있습니다.
SELECT DATEDIFF(YY, DateOfBirth, GETDATE()) -
CASE WHEN RIGHT(CONVERT(VARCHAR(6), GETDATE(), 12), 4) >=
RIGHT(CONVERT(VARCHAR(6), DateOfBirth, 12), 4)
THEN 0 ELSE 1 END AS AGE
이것은 생년월일과 현재 날짜 사이의 연도 차이를 가져옵니다. 생년월일이 아직 지나지 않으면 1 년을 뺍니다.
윤년이나 생년월일에 관계없이 항상 정확합니다.
무엇보다도-기능이 없습니다.