2017-01-11 6 views
3

SQL Server 2012에서 보고서의 Aging Years Field를 계산할 때 도움이 필요합니다.SQL에서 연대순 계산

기본적으로, 두 개의 필드 StartDateTime 및 EndDateTime이 여기에 아래의 몇 가지 샘플 데이터입니다 :

StartDateTime     EndDateTime 

2006-10-10 16:08:13.523  2008-04-11 00:00:00.000 
2016-05-11 13:03:48.093  2016-06-16 00:00:00.000 
2016-08-01 12:44:42.990  2016-08-01 00:00:00.000 
2016-05-20 17:33:27.957  2016-05-25 00:00:00.000 
2006-10-19 21:41:41.350  NULL 

나는 현재 정확한 가능한 한 (두 필드 사이의 노화 년을 계산하는 AgingYears 필드를 만들려고 노력하고 있어요) EndDateTime이 NULL 일 때 GETDATE()와 StartDateTime의 차이를 계산해야합니다. StartDateTime이 EndDateTime보다 큰 경우 (내가 왜 이와 같은 데이터가 있는지 모르지만) 0을 반환해야합니다.

내가 발견 한 웹 사이트를 기반으로 몇 가지 코드를 시도했지만, 하지만 그다지 도움이 안되는데 여기가 내가 붙어있는 곳입니다 :

내 코드에 도움이된다면 도움이 될 것입니다.

+0

당신이 당신의 샘플 데이터에서 원하는 결과를 보여줄 수 있습니까? – Aducci

+0

[생년월일 및 getDate()를 기준으로 연령 (년)을 계산하는 방법] (http://stackoverflow.com/questions/1572110/how-to-calculate-age-in-years-based- 생년월일 및 생년월일) –

+1

@ JeremyDanyow 그 다른 질문에 대한 대부분의 대답은 컴퓨팅 시대에 대한 접근법을 가지고있는 다른 사람들이 있다고 확신하지만 분명히 복잡하고 잘못된 것 같습니다 언어에 관계없이) – shawnt00

답변

2

윤년에주의하십시오. 2 월 29 일부터 2 월 28 일까지 어떻게 대우 받으시겠습니까? 그것은 긴 줄에있는 스크롤 막대없이 더 나은 모습 때문에

case 
    when year(coalesce(EndDateTime, getdate()) > year(StartDateTime) 
    then 
     datediff(year, StartDateTime, coalesce(EndDateTime, getdate())) - 
     case 
      when 
       EndDateTime is not null and 
        datepart(month, EndDateTime) < datepart(month, StartDateTime) 
       or datepart(month, EndDateTime) = datepart(month, StartDateTime) 
       and datepart(day, EndDateTime) < datepart(day, StartDateTime) 
      then 1 
      when 
       EndDateTime is null and 
        datepart(month, getdate()) < datepart(month, StartDateTime) 
       or datepart(month, getdate()) = datepart(month, StartDateTime) 
       and datepart(day, getdate()) < datepart(day, StartDateTime) 
      then 1 
      else 0 
     end 
    else 0 
end 

나는 대부분 EndDateTimegetdate()가지 경우 분할.

날짜가 엄격하게 일치하지 않아도 로직을 조정하고 윤년 조건을 전체 연도로 간주하는 한 가지 방법이 있습니다. 위의 방법으로 "분할"논리를 유지한다면이 표현식을 복사해야합니다 (대체 getdate() for EndDateTime everywhere except the은 null 테스트입니다). 당신이 접근 방식을 이해하면

http://rextester.com/SBH69843

  when 
       EndDateTime is not null and 
        datepart(month, EndDateTime)  < datepart(month, StartDateTime) 
       or datepart(month, EndDateTime)  = datepart(month, StartDateTime) 
       and datepart(day, EndDateTime)  < datepart(day, StartDateTime) 
       and not -- here's one way to catch the leap day condition 
       (
        -- adding one day this way is deprecated and only works with datetime 
        and datepart(month, StartDateTime + 1) > datepart(month, StartDateTime) 
        and datepart(month, EndDateTime + 1) > datepart(month, EndDateTime) 
       ) 

는, BTW YYYYMMDD 형식의 숫자에 연산을 사용하여 동일한 논리를 응축 할 수있는 방법이있다.

(
cast(convert(varchar(8), @EndDateTime, 120) as int) - 
cast(convert(varchar(8), @StartDateTime, 120) as int) 
)/10000 

위의 모든 복잡한 논리는 간단히 빼기에서 수십 년을 빌린 것입니다. 그것은 거의 같은 것입니다.

+0

이것은 필요 이상으로 복잡해 보입니다. –

+0

전혀 복잡하지 않습니다. 이것은 날짜를 (다른 연도의) 날짜순으로 정렬하고 일별로 정렬하는 일반적인 방법입니다. – shawnt00

1

나는 그것을 같이해야한다고 생각 :

SELECT StartDate 
    , EndDate 
    , CASE 
     WHEN DATEDIFF(YY, StartDate, ISNULL(EndDate, GETDATE())) < 0 
      THEN 0 
     ELSE DATEDIFF(YY, StartDate, ISNULL(EndDate, GETDATE())) 
     END AS AgingYears 
FROM YourTableName