-1

I need to write a query where it looks at a plethora of dates and determines if that date was 3 or more years ago, 2 or more years ago, 1 or more year ago, 6 or more months ago, or less than 6 months ago. Is there a way to do this without writing in physical dates, so that the analysis can be run again later without needing to change the dates? I have not started to write the query yet, but I have been trying to map it out first.

Manda Kirk
  • 13
  • 6
  • Possible duplicate of [How to compare two dates to find time difference in SQL Server 2005, date manipulation](https://stackoverflow.com/questions/9521434/how-to-compare-two-dates-to-find-time-difference-in-sql-server-2005-date-manipu) – Tab Alleman Aug 09 '17 at 13:04

3 Answers3

1

You should use case. I would recommend something like:

select (case when datecol < dateadd(year, -3, getdate()) as '3 years ago'
             when datecol < dateadd(year, -2, getdate()) as '2 years ago'
             . . .
        end)

I specifically do not recommend using datediff(). It is counterintuitive because it counts the number of "boundaries" between two dates. So, 2016-12-31 and 2017-01-01 are one year apart.

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
  • We was thinking in the same way but I filtered rows instead of "classifying" them. The only thing is wrong in your "classification" is that when datecol < dateadd(year, -3, getdate()) means MORE than 3 years ago, not exactly 3 years ago – sepupic Aug 09 '17 at 13:11
0

You can use the DATEDIFF function to calculate the number of months, days, years, etc. between two dates, e.g.

select datediff(day, '2016-01-01', '2017-01-01')

returns 366, because 2016 was a leap year

To get the current date, use the GETDATE() function.

Jonas Høgh
  • 10,358
  • 1
  • 26
  • 46
0

I tend to use a generic Tier Table for several reasons.

  1. Logic is moved from code.
  2. Alternate Tiers may be deployed depending on your audience.
  3. Most importantly, things change.

The following will generate a series of dates, and then summarize by the desired tier. I should add, this is a simplified example

Example

-- Create Sample Tier Table
Declare @Tier table (Tier_Group varchar(50),Tier_Seq int,Tier_Title varchar(50),Tier_R1 int,Tier_R2 int)
Insert into @Tier values
 ('MyAgeTier',1,'+3 Years'       ,36,999999)
,('MyAgeTier',2,'2 - 3 Years'    ,24,36)
,('MyAgeTier',3,'1 - 2 Years'    ,12,24)
,('MyAgeTier',4,'6 Mths - 1 Year',6 ,12)
,('MyAgeTier',5,'<6 Mths'        ,0 ,6)
,('MyAgeTier',6,'Total '         ,0 ,999999)

Select Tier_Title
      ,Dates   = count(*)
      ,MinDate = min(D)
      ,MaxDate = max(D)
 From  @Tier A
 Join (
        -- Your Actual Source
        Select Top (DateDiff(DAY,'2010-01-01','2017-07-31')+1) 
               D=cast(DateAdd(DAY,-1+Row_Number() Over (Order By (Select Null)),'2010-01-01') as date)
         From  master..spt_values n1,master..spt_values n2
      ) B
 On Tier_Group = 'MyAgeTier' and DateDiff(MONTH,D,GetDate()) between Tier_R1 and Tier_R2-1
 Group By Tier_Title,Tier_R1
 Order by Tier_R1 Desc

Returns (this example)

enter image description here

John Cappelletti
  • 79,615
  • 7
  • 44
  • 66