생년월일 및 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.