생년월일 및 getDate ()를 기준으로 연령 (년)을 계산하는 방법


171

생년월일 (현재 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

16
데이터베이스의 기본 날짜 또는 날짜 / 시간 유형을 사용하는 대신 nvarchar (25)를 사용하여 날짜 값을 문자열로 저장하는 이유는 무엇입니까?
Jesper

이 질문에는 2005 년이 아니라 2005 년으로 태그가 지정되어 있으므로 기본 '날짜'유형을 사용할 수 없지만 확실히 날짜 시간이며 정확도가 필요하지 않기 때문에 SmallDateTime이라고 할 수 있습니다.
Andrew

안녕하세요, varchar로 날짜를 유지하는 이유는 SQL이 아닌 서버 스키마에서 이것을 가져 오기 때문에 날짜 시간 (및 다른 날짜 형식)으로 가져 오는 데 문제가 있었고 varchar가 ok로 변환 한 것입니다.
Jimmy

7
@ James.Elsey, 당신은 가져 오기에 문제가 있었고 결과적으로 모든 날짜가 유효합니까? varchar와 함께 datetime 또는 smalldatetime을 사용하지 않으면 확실하지 않을 수 있습니다. 가져 오기가 작동하지만 다른 문제가 있습니다. 또한 나는 나이를 저장하지 않았으며 매일 바뀌고 View
KM을

@KM 예, 데이터를 날짜로 가져 오는 데 문제가 있었으며, 당시 유일하게 실행 가능한 솔루션은 nvarchars로 가져 오는 것입니다. 이 선택은 야간 작업의 일부가 될 것이므로 나이 저장은 문제가되지 않아야합니다.
Jimmy

답변:


256

윤년 / 일 및 다음 방법에 문제가 있습니다. 아래 업데이트를 참조하십시오.

이 시도:

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

24
이것은 또한 정확한 해결책이 아닙니다. 내 자신의 @dob를 '1986-07-05 00:00:00'으로 가져 와서 GETDATE()'2013-07-04 23:59:59'에서 이것을 실행하면 (다른 변수 대신 ) 사용 합니다. 27 살인데, 아직은 아니에요 예제 코드 : declare @startDate nvarchar(100) = '1986-07-05 00:00:00' declare @endDate nvarchar(100) = '2013-07-04 23:59:59' SELECT DATEDIFF(hour,@startDate,@endDate)/8766.0 AS AgeYearsDecimal ,CONVERT(int,ROUND(DATEDIFF(hour,@startDate,@endDate)/8766.0,0)) AS AgeYearsIntRound ,DATEDIFF(hour,@startDate,@endDate)/8766 AS AgeYearsIntTrunc
bartlaarhoven

20
연간 8766 시간, 365.25 일로 가정하기 때문에 정확하지 않습니다. 365.25 일의 연도는 없기 때문에,이 날짜는 사람의 생년월일 근처에있는 것보다 정확하지 않을 수 있습니다. 이 방법 은 여전히 ​​더 정확할 것입니다.
베이컨 비트

1
두 번째 @ 베이컨 비트 주석-현재 날짜가 사람의 생년월일 근처 인 경우 종종 잘못된 것입니다.
플래시

2
첫 번째 텍스트 블록 이이 대답을 혼란스럽게 생각합니다. 업데이트 된 방법에 윤년 문제가 없으면 답변을 맨 아래로 옮기십시오 (실제로 유지하려는 경우).
ajbeaven

1
정확한 계산 을 원한다면 DATEDIFF는 @ShailendraMishra를 수행하지 않습니다. 날짜 등을 근사하기 때문입니다. 예를 들어, select datediff(year, '2000-01-05', '2018-01-04')17이 아닌 18을 반환합니다. 위의 예를 "INTE IN IN YEARS IN INT"의 제목 아래에서 사용했으며 완벽하게 작동합니다. 감사!
openwonk

132

이걸 버려야 해. 당신이 경우 변환 숫자로 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

14
이것은 모든 윤년 문제를 해결하는 방법에서 거의 마술입니다. 112는 날짜를 yyyymmdd로 형식화하는 CONVERT 함수의 특수 번호입니다. 당신이 그것을 볼 때 모두에게 분명하지 않을 수 있습니다.
Derek Tomes

5
너는 천재 야!
ercan

우리 팀이 나이를 찾는 데 사용한 날짜가 우리가 비교하는 날짜와 같은 날인 경우 문제가 발생했습니다. 우리는 그들이 같은 날에 (그리고 나이가 홀수 일 경우) 나이가 1만큼 줄어든다는 것을 알았습니다. 이것은 완벽하게 작동했습니다!
ek eek

1
정답입니다. 그렇게 표시하십시오.
Snympi

4
SQL Server 2012+에서 이와 동일한 계산 방법을위한 가장 간단한 / 가장 짧은 코드는 다음과 같습니다.code: SELECT [Age] = (0+ FORMAT(@as_of,'yyyyMMdd') - FORMAT(@bday,'yyyyMMdd') ) /10000 --The 0+ part tells SQL to calc the char(8) as numbers
ukgav

44

거의 10 년 동안 프로덕션 코드에서이 쿼리를 사용했습니다.

SELECT FLOOR((CAST (GetDate() AS INTEGER) - CAST(Date_of_birth AS INTEGER)) / 365.25) AS Age

6
나쁘지는 않지만 100 %는 아닙니다. 2007/10/16은 2009/10/15에 2 세가됩니다
Andrew

4
Doh, 우리는 명백한 것을 놓치고 있습니다. 그것은 정오 이후입니다. getdate는 정수를 반환하므로 물론 반올림됩니다. 나는 당신의 대답을 붙여 넣고 그것을 실행했기 때문에 리터럴이 아닌 자동으로 getdate를 사용했습니다.
Andrew

2
우아하고 간단합니다. 감사!
William MB

9
우리가 인간 연령에 대해 이야기하고 있다면, 인간이 연령을 계산하는 방식으로 계산해야합니다. 지구가 얼마나 빨리 움직이는 지, 달력과 관련된 모든 것과는 아무런 관련이 없습니다. 생년월일과 같은 달과 일이 경과 할 때마다 나이가 1 씩 증가합니다. 이는 다음과 같이 인간이 "나이"라고 말할 때 의미하는 내용을 반영하기 때문에 가장 정확합니다.DATEDIFF(yy, @BirthDate, GETDATE()) - CASE WHEN (MONTH(@BirthDate) >= MONTH(GETDATE())) AND DAY(@BirthDate) > DAY(GETDATE()) THEN 1 ELSE 0 END
Bacon Bits

5
죄송합니다. 구문이 잘못되었습니다. CASE WHEN (MONTH(@date) > MONTH(GETDATE())) OR (MONTH(@date) = MONTH(GETDATE()) AND DAY(@date) > DAY(GETDATE())) THEN 1 ELSE 0 END
베이컨 비트

31

위의 많은 솔루션이 잘못되었습니다 .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

100을 곱한 이유는 무엇입니까? 코드 라이브러리에 존재하는 것을 데이터베이스에서 복제하려고 할 때 유용합니다.하지만 함수를 설명 할 수 없습니다. 이것은 바보 같은 질문 일 수 있습니다 :)
Jen

6
감사! 정확히 내가 여기에 기대했던 코드. 이것은 (못생긴) 문자열 변환 없이이 스레드에서 유일하게 정확한 코드입니다! @Jen DoB의 월과 일 (예 : 9 월 25 일)을 정수 값 0925(또는 925) 으로 바꿉니다 . 현재 날짜와 동일하게 수행하고 (12 월 16 일처럼 1216) DoB 정수 값이 이미 통과했는지 확인합니다. 이 정수를 만들려면 월에 100을 곱해야합니다.
bartlaarhoven

감사합니다 @bartlaarhoven :)
Jen

문자열 변환을 피하는 대신 많은 캐스팅을 수행한다고 언급합니다. 내 테스트에 따르면 dotjoe의 답변 보다 훨씬 빠르지 않으며 코드가 더 장황합니다.
StriplingWarrior

허용되는 답변에는 훨씬 간단한 INT 답변이 있습니다.(CONVERT(int,CONVERT(char(8),@Now,112))-CONVERT(char(8),@Dob,112))/10000
KM.

19

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 세가 된 것으로 간주됩니다.


@Andrew-수정 됨-대체 중 하나를 놓쳤습니다
Ed Harper

1
단순화 된 버전SELECT DATEDIFF(year, DOB, getdate()) + CASE WHEN (DATEADD(year,DATEDIFF(year, DOB, getdate()) , DOB) > getdate()) THEN - 1 ELSE 0 END)
Peter

이것이 올바른 접근법입니다. 나는 왜 핵이 그렇게 많이 불쾌한 지 이해하지 못한다.
살만 A

8

편집 :이 답변이 잘못되었습니다. 나는 여기 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()결국 필요합니다.


이것은 투표로 선정되거나 답으로 표시되어야합니다. 짧고 우아하며 논리적으로 정확합니다.
z00l

1
2 월 이후에 태어난 모든 사람의 경우,이 DayOfYear방법을 사용하여 윤년마다 하루 일찍 나이를 증가시킵니다 .
AeroX

4
@AeroX이 결함을 발견해 주셔서 감사합니다. 나는 솔루션을 사용했거나 사용했던 사람에게 경고로 솔루션을 남기기로 결정 dayofyear했지만 왜 잘못되었는지 보여주기 위해 명확하게 편집했습니다. 나는 그것이 적합하기를 바랍니다.
JonBrave

5

항상 정확한 나이를 제공하는 간단한 대답이 없기 때문에 여기에 내가 생각해 낸 것이 있습니다.

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 년을 뺍니다.

윤년이나 생년월일에 관계없이 항상 정확합니다.

무엇보다도-기능이 없습니다.


3
SELECT ID,
Name,
DATEDIFF(yy,CONVERT(DATETIME, DOB),GETDATE()) AS AGE,
DOB
FROM MyTable

1
첫 번째가 아닌 두 번째 인수로 getdate를 원합니다. 그렇지 않으면 음수 결과가 나오고 datediff가 반올림되므로 select datediff (yy, '20081231', getdate ())는 1 세를보고하지만 10 개월이 지나야합니다. .
Andrew

1
이 계산은 올해 아직 생일을하지 않은 사람들에게 잘못된 계산을 제공합니다.

3

이건 어떤가요:

DECLARE @DOB datetime
SET @DOB='19851125'   
SELECT Datepart(yy,convert(date,GETDATE())-@DOB)-1900

반올림, 잘림 및 설정 문제를 피하지 않겠습니까?


계산이 정확하지 않습니다. 예를 들어 '1986-07-05 00:00:00'DOB와 '2013-07-04 23:59:59'현재 시간 을 가져 가면 실패합니다 .
drinovc 2016 년

@ub_coding 다른 질문을 제공하고 답변하거나 질문하십니까?
Aaron C

this : DECLARE @DOB datetime SET @ DOB = '19760229'SELECT Datepart (yy, convert (datetime, '19770228')-@ DOB) -1900 = 1 주요 문제는 대부분의 솔루션에 대해 29 차이이며 반올림 등을 설명합니다. .
레오나르도 마르케스 드 수자

3

나는 이것이 여기에 게시 된 다른 것들과 비슷하다고 생각합니다 ....이 솔루션은 윤년 예제 02/29/1976에서 03/01/2011에 효과가 있었고 첫해의 경우에도 효과가있었습니다. 07/04 윤년 솔루션에 대해 마지막으로 게시 한 첫 번째 사례는 첫해 유스 케이스에서 작동하지 않았습니다.

SELECT FLOOR(DATEDIFF(DAY, @date1 , @date2) / 365.25)

찾을 여기 .


3

아래 답변이 가능한지 확인하십시오.

DECLARE @BirthDate DATE = '09/06/1979'

SELECT 
 (
 YEAR(GETDATE()) - YEAR(@BirthDate) - 
 CASE  WHEN (MONTH(GETDATE()) * 100) + DATEPART(dd, GETDATE()) >     
 (MONTH(@BirthDate) * 100) + DATEPART(dd, @BirthDate)
 THEN 1             
 ELSE 0             
 END        
 )

2
DECLARE @DOB datetime
set @DOB ='11/25/1985'

select floor(
( cast(convert(varchar(8),getdate(),112) as int)-
cast(convert(varchar(8),@DOB,112) as int) ) / 10000
)

출처 : http://beginsql.wordpress.com/2012/04/26/how-to-calculate-age-in-sql-server/


SQL Server 2012+에서이 작업을 수행하는 짧은 방법은 다음과 같으며 112 로의 변환을 피하고 바닥이 필요하지 않습니다.code: SELECT [Age] = (0+ FORMAT(@ToDate,'yyyyMMdd') - FORMAT(@DOB,'yyyyMMdd') ) /10000
ukgav

2

나는 이것에 대해 많은 생각과 검색을했으며 3 가지 해결책이 있습니다.

  • 나이를 정확하게 계산
  • 짧다 (주로)
  • (대부분) 매우 이해할 수 있습니다.

테스트 값은 다음과 같습니다.

DECLARE @NOW DATETIME = '2013-07-04 23:59:59' 
DECLARE @DOB DATETIME = '1986-07-05' 

솔루션 1 : 하나의 js 라이브러리 에서이 방법을 찾았습니다. 내가 가장 좋아하는 것입니다.

DATEDIFF(YY, @DOB, @NOW) - 
  CASE WHEN DATEADD(YY, DATEDIFF(YY, @DOB, @NOW), @DOB) > @NOW THEN 1 ELSE 0 END

실제로 DOB에 연도 차이를 추가하고 현재 날짜보다 크면 1 년을 뺍니다. 간단 하죠? 유일한 것은 여기에 연도 차이가 복제된다는 것입니다.

그러나 인라인을 사용할 필요가 없으면 다음과 같이 작성할 수 있습니다.

DECLARE @AGE INT = DATEDIFF(YY, @DOB, @NOW)
IF DATEADD(YY, @AGE, @DOB) > @NOW
SET @AGE = @AGE - 1

해결책 2 : 이것은 원래 @ bacon-bits에서 복사 한 것입니다. 이해하기가 가장 쉽지만 조금 길다.

DATEDIFF(YY, @DOB, @NOW) - 
  CASE WHEN MONTH(@DOB) > MONTH(@NOW) 
    OR MONTH(@DOB) = MONTH(@NOW) AND DAY(@DOB) > DAY(@NOW) 
  THEN 1 ELSE 0 END

기본적으로 인간이 나이를 계산합니다.


해결책 3 : 친구가 이것을 다음과 같이 리팩토링했습니다.

DATEDIFF(YY, @DOB, @NOW) - 
  CEILING(0.5 * SIGN((MONTH(@DOB) - MONTH(@NOW)) * 50 + DAY(@DOB) - DAY(@NOW)))

이것은 가장 짧지 만 이해하기가 가장 어렵습니다. 50월이 같을 때만 차이가 중요하므로 하루의 차이 만 중요합니다. SIGN함수는 -1, 0 또는 1로 가져 가치를 어떤 변환하기위한 것입니다 CEILING(0.5 *과 동일 Math.max(0, value)하지만, SQL에서 그런 일이 없다.


1
CASE WHEN datepart(MM, getdate()) < datepart(MM, BIRTHDATE) THEN ((datepart(YYYY, getdate()) - datepart(YYYY, BIRTH_DATE)) -1 )
     ELSE 
        CASE WHEN datepart(MM, getdate()) = datepart(MM, BIRTHDATE)
            THEN 
                CASE WHEN datepart(DD, getdate()) < datepart(DD, BIRTHDATE) THEN ((datepart(YYYY, getdate()) - datepart(YYYY, BIRTHDATE)) -1 )
                    ELSE (datepart(YYYY, getdate()) - datepart(YYYY, BIRTHDATE))
                END
        ELSE (datepart(YYYY, getdate()) - datepart(YYYY, BIRTHDATE)) END            
    END

1
select floor((datediff(day,0,@today) - datediff(day,0,@birthdate)) / 365.2425) as age

여기에 365.25 답변이 많이 있습니다. 윤년 정의 방법을 기억하십시오 :

  • 4 년마다
    • 100 년마다를 제외하고
      • 400 년을 제외하고

훌륭한 답변입니다. 여기에 호기심이 사람들을 위해 365.2425 사용에 대한 올바른 값입니다 이유에 대한 설명은 다음과 같습니다 grc.nasa.gov/WWW/k-12/Numbers/Math/Mathematical_Thinking/...
vvvv4d

0

이건 어때요:

SET @Age = CAST(DATEDIFF(Year, @DOB, @Stamp) as int)
IF (CAST(DATEDIFF(DAY, DATEADD(Year, @Age, @DOB), @Stamp) as int) < 0) 
    SET @Age = @Age - 1

0

이 시도

DECLARE @date datetime, @tmpdate datetime, @years int, @months int, @days int
SELECT @date = '08/16/84'

SELECT @tmpdate = @date

SELECT @years = DATEDIFF(yy, @tmpdate, GETDATE()) - CASE WHEN (MONTH(@date) > MONTH(GETDATE())) OR (MONTH(@date) = MONTH(GETDATE()) AND DAY(@date) > DAY(GETDATE())) THEN 1 ELSE 0 END
SELECT @tmpdate = DATEADD(yy, @years, @tmpdate)
SELECT @months = DATEDIFF(m, @tmpdate, GETDATE()) - CASE WHEN DAY(@date) > DAY(GETDATE()) THEN 1 ELSE 0 END
SELECT @tmpdate = DATEADD(m, @months, @tmpdate)
SELECT @days = DATEDIFF(d, @tmpdate, GETDATE())

SELECT Convert(Varchar(Max),@years)+' Years '+ Convert(Varchar(max),@months) + ' Months '+Convert(Varchar(Max), @days)+'days'

0

이 솔루션을 사용해보십시오 :

declare @BirthDate datetime
declare @ToDate datetime

set @BirthDate = '1/3/1990'
set @ToDate = '1/2/2008'
select @BirthDate [Date of Birth], @ToDate [ToDate],(case when (DatePart(mm,@ToDate) <  Datepart(mm,@BirthDate)) 
        OR (DatePart(m,@ToDate) = Datepart(m,@BirthDate) AND DatePart(dd,@ToDate) < Datepart(dd,@BirthDate))
        then (Datepart(yy, @ToDate) - Datepart(yy, @BirthDate) - 1)
        else (Datepart(yy, @ToDate) - Datepart(yy, @BirthDate))end) Age

0

생일 및 반올림 문제를 올바르게 처리합니다.

DECLARE @dob  datetime
SET @dob='1992-01-09 00:00:00'

SELECT DATEDIFF(YEAR, '0:0', getdate()-@dob)

2
윤년을 올바르게 처리하지 않습니다. SELECT DATEDIFF (YEAR, '0 : 0', convert (datetime, '2014-02-28') -'2012-02-29 ')는 2를 제공하지만 1이어야합니다.
Peter Kerr

0

Ed Harper의 솔루션은 내가 찾은 가장 간단한 방법으로 두 날짜의 월과 일이 1 일 이하일 때 잘못된 대답을 반환하지 않습니다. 나는 부정적인 연령을 처리하기 위해 약간 수정했습니다.

DECLARE @D1 AS DATETIME, @D2 AS DATETIME
SET @D2 = '2012-03-01 10:00:02'
SET @D1 = '2013-03-01 10:00:01'
SELECT
   DATEDIFF(YEAR, @D1,@D2)
   +
   CASE
      WHEN @D1<@D2 AND DATEADD(YEAR, DATEDIFF(YEAR,@D1, @D2), @D1) > @D2
      THEN - 1
      WHEN @D1>@D2 AND DATEADD(YEAR, DATEDIFF(YEAR,@D1, @D2), @D1) < @D2
      THEN 1
      ELSE 0
   END AS AGE

0

정답으로 표시된 답변은 정확성에 더 가깝지만 다음 시나리오에서는 실패합니다. 출생 연도는 윤년이고 일은 2 월 월 이후입니다.

declare @ReportStartDate datetime = CONVERT(datetime, '1/1/2014'),
@DateofBirth datetime = CONVERT(datetime, '2/29/1948')

FLOOR(DATEDIFF(HOUR,@DateofBirth,@ReportStartDate )/8766)


또는

FLOOR(DATEDIFF(HOUR,@DateofBirth,@ReportStartDate )/8765.82) -- Divisor is more accurate than 8766

-다음 솔루션은 더 정확한 결과를 제공합니다.

FLOOR(DATEDIFF(YEAR,@DateofBirth,@ReportStartDate) - (CASE WHEN DATEADD(YY,DATEDIFF(YEAR,@DateofBirth,@ReportStartDate),@DateofBirth) > @ReportStartDate THEN 1 ELSE 0 END ))

윤년, 날짜 29 29 년 등을 고려하여 거의 모든 시나리오에서 작동했습니다.

이 수식에 허점이있는 경우 수정하십시오.


최종 공식은이 답변 stackoverflow.com/a/1572235/168747 과 거의 동일 합니다. 그러나 여기있는 것은 읽기 어렵고 불필요 floor합니다.
Marek

0
Declare @dob datetime
Declare @today datetime

Set @dob = '05/20/2000'
set @today = getdate()

select  CASE
            WHEN dateadd(year, datediff (year, @dob, @today), @dob) > @today 
            THEN datediff (year, @dob, @today) - 1
            ELSE datediff (year, @dob, @today)
        END as Age

0

다음은 생년월일과 현재 날짜를 기준으로 나이를 계산하는 방법입니다.

select case 
            when cast(getdate() as date) = cast(dateadd(year, (datediff(year, '1996-09-09', getdate())), '1996-09-09') as date)
                then dateDiff(yyyy,'1996-09-09',dateadd(year, 0, getdate()))
            else dateDiff(yyyy,'1996-09-09',dateadd(year, -1, getdate()))
        end as MemberAge
go

0
CREATE function dbo.AgeAtDate(
    @DOB    datetime,
    @CompareDate datetime
)

returns INT
as
begin

return CASE WHEN @DOB is null
THEN 
    null
ELSE 
DateDiff(yy,@DOB, @CompareDate) 
- CASE WHEN datepart(mm,@CompareDate) > datepart(mm,@DOB) OR (datepart(mm,@CompareDate) = datepart(mm,@DOB) AND datepart(dd,@CompareDate) >= datepart(dd,@DOB))
  THEN 0 
  ELSE 1
  END
END
End

GO

-1 : 언제든지 잘못 될 수 있습니다 ( 예 month(compare) > month(dob):) . day(compare) < day(dob)select dbo.AgeAtDate('2000-01-14', '2016-02-12')
JonBrave

맞습니다,이 경우 감사합니다, 기능이 업데이트되었습니다
Vova

0
DECLARE @FromDate DATETIME = '1992-01-2623:59:59.000', 
        @ToDate   DATETIME = '2016-08-10 00:00:00.000',
        @Years INT, @Months INT, @Days INT, @tmpFromDate DATETIME
SET @Years = DATEDIFF(YEAR, @FromDate, @ToDate)
 - (CASE WHEN DATEADD(YEAR, DATEDIFF(YEAR, @FromDate, @ToDate),
          @FromDate) > @ToDate THEN 1 ELSE 0 END) 


SET @tmpFromDate = DATEADD(YEAR, @Years , @FromDate)
SET @Months =  DATEDIFF(MONTH, @tmpFromDate, @ToDate)
 - (CASE WHEN DATEADD(MONTH,DATEDIFF(MONTH, @tmpFromDate, @ToDate),
          @tmpFromDate) > @ToDate THEN 1 ELSE 0 END) 

SET @tmpFromDate = DATEADD(MONTH, @Months , @tmpFromDate)
SET @Days =  DATEDIFF(DAY, @tmpFromDate, @ToDate)
 - (CASE WHEN DATEADD(DAY, DATEDIFF(DAY, @tmpFromDate, @ToDate),
          @tmpFromDate) > @ToDate THEN 1 ELSE 0 END) 

SELECT @FromDate FromDate, @ToDate ToDate, 
       @Years Years,  @Months Months, @Days Days

0

윤년에 대해 걱정하지 않고 수학이 아닌 날짜 함수 만있는 솔루션은 어떻습니까?

CREATE FUNCTION dbo.getAge(@dt datetime) 
RETURNS int
AS
BEGIN
    RETURN 
        DATEDIFF(yy, @dt, getdate())
        - CASE 
            WHEN 
                MONTH(@dt) > MONTH(GETDATE()) OR 
                (MONTH(@dt) = MONTH(GETDATE()) AND DAY(@dt) > DAY(GETDATE())) 
            THEN 1 
            ELSE 0 
        END
END

0

MANY 메소드를 시도한 후에는 스타일 112로 변환하는 대신 최신 MS SQL FORMAT 함수를 사용하여 시간의 100 %가 작동합니다. 작동하지만 가장 적은 코드입니다.

아무도 작동하지 않는 날짜 조합을 찾을 수 있습니까? 나는 하나가 있다고 생각하지 않습니다 :)

--Set parameters, or choose from table.column instead:

DECLARE @DOB    DATE = '2000/02/29' -- If @DOB is a leap day...
       ,@ToDate DATE = '2018/03/01' --...there birthday in this calculation will be 

--0+ part tells SQL to calc the char(8) as numbers:
SELECT [Age] = (0+ FORMAT(@ToDate,'yyyyMMdd') - FORMAT(@DOB,'yyyyMMdd') ) /10000

-2

우리는 여기와 같은 것을 사용했지만 평균 연령을 취했습니다.

ROUND(avg(CONVERT(int,DATEDIFF(hour,DOB,GETDATE())/8766.0)),0) AS AverageAge

라운드는 내부가 아니라 외부에 있습니다. 이를 통해 AVG가보다 정확 해지며 한 번만 ROUND 할 수 있습니다. 더 빠르게 만들기.


-2
select DATEDIFF(yy,@DATE,GETDATE()) -
case when DATEPART(mm,GETDATE())*100+DATEPART(dd,GETDATE())>=
DATEPART(mm,@DATE)*100+DATEPART(dd,@DATE) THEN 0
ELSE 1 END 

-2
SELECT CAST(DATEDIFF(dy, @DOB, GETDATE()+1)/365.25 AS int)

나는 아래로 표를 보았지만 이것이 깨 졌다는 것을 증명하는 예는 보지 못했다.
Alex
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.