I think there are two possible ways:
(1) Save date substrings , for example:
'2013' -- year 2013 '2013-01' -- year 2013, January '2013-01-01' -- year 2013, January 1
(2) Save 3 different columns , Year, Month, Day (and you can create an index of Year + Month + Date without any problems)
2013 null null -- year 2013 2013 1 null -- year 2013, January 2013 1 1 -- year 2013, January 1st
Which one is best depends on how you want to request data. Suppose you have a stored procedure, and you want to pass a parameter so that all rows fall into state.
In case (1), you pass the string @Date = '2013-01' as a parameter, and you want to get all the rows where year = 2013 and month = 01. So the where clause will look like
where left(Date, len(@Date)) = @Date
In case (2), you pass three parameters - @Year = 2013, @Month = 1, @Day = null , and the where clause will look something like this:
where Year = @Year and -- Supposing @Year is always not null (@Month is null or @Month is not null and Month = @Month) and (@Day is null or @Day is not null and Day = @Day)
This can be more complicated depending on how you want to process the strings. For example, if you specify a parameter of type 2013-01 , do you want to get strings where month = null or not?
On the other hand, if you want to pass a date and check if it falls into the date range, then the Gordon Linoff suggestion is good to use.