2015-04-06 2 views
1

Действительно длинный рассказ короткий, у меня есть два поля datetime в таблице, которые я загружаю в переменные @DateFrom и @DateTo, и мне нужно " объясните, какой диапазон они охватывают в тексте для презентации на экране. Хотя поля являются datetime, компонент времени будет проигнорирован. Я также объявляю @Current как datetime для хранения результата getDate(), в случае, если мне нужно отключить время перед сравнением.T-SQL Ищете наиболее сжатый способ суммирования диапазона дат начала и окончания

Как такого рода вещи не очень редко, я надеюсь, что кто-то это сделал раньше.

Некоторые примеры (я буду использовать сегодняшнюю дату 6 апреля 2015 года для @Current):

If @DateFrom is April 6, 2015, and @DateTo is also April 6, 2015, return "Today" 
If @DateFrom is April 5, 2015, and @DateTo is also April 5, 2015, return "Yesterday" 
If @DateFrom is April 2, 2015, and @DateTo is April 6, 2015, return "Last 4 days" 
If @DateFrom is March 29, 2015, and @DateTo is April 4, 2015, return "Last week" 
    (March 29 is Sunday, and April 4 is Saturday). 
If @DateFrom is April 1, 2015, and @DateTo is April 30, 2015, return "This month" 
If @DateFrom is March 1, 2015, and @DateTo is March 31, 2015, return "Last month" 
If @DateFrom is March 28, 2015, and @DateTo is April 5, 2015, 
    return "From March 28, 2015 To April 5, 2015" 
    (because it doesn't fit any of the standard date ranges). 

Я надеюсь, что кто-то опубликовал код для функции или хранимой процедуры, чтобы сделать это или очень похоже где-то , поэтому мне не нужно изобретать велосипед.

+0

Почему '@ Current' просто' DATE', так как «компонент времени будет проигнорирован»? –

+0

Хорошая точка, что делает окончательный код максимально чистым и легким. – Dan

ответ

1

немного некрасиво , но, вероятно, лучший T-SQL можно сделать:

DECLARE @DateFrom DATE, @DateTo DATE 
DECLARE @Current DATE = GETDATE() 

DECLARE @BeginningOfLastWeek DATE = DATEADD(WEEK, DATEDIFF(WEEK,0,GETDATE())-1,-1) 
DECLARE @EndOfLastWeek DATE = DATEADD(DAY, 6, @BeginningOfLastWeek) 

DECLARE @BeginningOfCurrentMonth DATE = DATEADD(MONTH, DATEDIFF(MONTH, 0, @Current), 0) 
DECLARE @EndOfCurrentMonth DATE = DATEADD(DAY, -1, DATEADD(MONTH, 1, @BeginningOfCurrentMonth)) 

DECLARE @BeginningOfLastMonth DATE = DATEADD(MONTH, DATEDIFF(MONTH, 0, @Current)-1, 0) 
DECLARE @EndOfLastMonth DATE = DATEADD(DAY, -1, DATEADD(MONTH, 1, @BeginningOfLastMonth)) 

SELECT 
    CASE 
     WHEN @DateFrom = @Current AND @DateTo = @Current THEN 'Today' 
     WHEN @DateFrom = DATEADD(d, -1, @Current) AND @DateTo = @DateFrom THEN 'Yesterday' 
     WHEN @DateFrom = DATEADD(d, -4, @Current) AND @DateTo = @Current THEN 'Last 4 Days' 
     WHEN @DateFrom = @BeginningOfLastWeek AND @DateTo = @EndOfLastWeek THEN 'Last week' 
     WHEN @DateFrom = @BeginningOfCurrentMonth AND @DateTo = @EndOfCurrentMonth THEN 'This month' 
     WHEN @DateFrom = @BeginningOfLastMonth AND @DateTo = @EndOfLastMonth THEN 'Last month' 
     ELSE 'From ' + CONVERT(nvarchar, @DateFrom, 107) + ' To ' + CONVERT(nvarchar, @DateTo, 107) 
    END 
+0

См. Ниже мое полное решение. – Dan

0

Я не знаю, функции или sproc, который уже построен, но есть что-то на сайте PINAL Дэйва, где вы можете скопировать-вставить и иметь 80% вашей функции готовы: http://blog.sqlauthority.com/2008/08/29/sql-server-few-useful-datetime-functions-to-find-specific-dates/

+0

Я уже использовал этот код от Pinal Dave, чтобы сделать то же самое, что я здесь делаю. Его код - это переход от квалифицированного выбора даты (т. Е. «Вчера») к значениям фактической даты, тогда как я беру фактические значения даты и стараюсь суммировать их как можно лучше. – Dan

0

Спасибо, @ thepirat000, я использовал большую часть вашего кода в моем окончательном решении, которое я ставлю ниже.

SELECT 
    CASE 
     WHEN @DateFrom = @Current AND @DateTo = @Current THEN 'Today' 
     WHEN @DateFrom = DATEADD(d, -1, @Current) AND @DateTo = @DateFrom THEN 'Yesterday' 
     WHEN @DateFrom = @BeginningOfLastWeek AND @DateTo = @EndOfLastWeek THEN 'Last week' 
     WHEN @DateFrom = @BeginningOfCurrentMonth AND @DateTo = @EndOfCurrentMonth THEN 'This month' 
     WHEN @DateFrom = @BeginningOfLastMonth AND @DateTo = @EndOfLastMonth THEN 'Last month' 
     WHEN DATEPART(m,@DateFrom) = DATEPART(m,@DateTo) AND DATEPART(d,@DateFrom) = 1 
      AND DATEPART(d,@DateTo) = datediff(day, dateadd(day, 1-day(@DateFrom), @DateFrom), dateadd(month, 1, dateadd(day, 1-day(@DateFrom), @DateFrom))) 
      THEN DATENAME(MM, @DateFrom) -- the name of the month 
     WHEN DATEPART(dy,@DateFrom) = DATEPART(dy,@DateTo) AND @DateTo = @Current THEN CAST(DATEDIFF(y,@DateFrom,@DateTo) AS varchar(2)) + ' years ago' 
     WHEN DATEPART(d,@DateFrom) = DATEPART(d,@DateTo) AND @DateTo = @Current THEN CAST(DATEDIFF(m,@DateFrom,@DateTo) AS varchar(2)) + ' months ago' 
     WHEN DATEPART(dw,@DateFrom) = DATEPART(dw,@DateTo) AND @DateTo = @Current THEN CAST(DATEDIFF(wk,@DateFrom,@DateTo) AS varchar(2)) + ' weeks ago' 
     WHEN DATEDIFF(dd,@DateFrom,@DateTo) < 30 AND @DateTo = @Current THEN CAST(DATEDIFF(d,@DateFrom,@DateTo) AS varchar(2)) + ' days ago' 
     ELSE 'From ' + CONVERT(nvarchar, @DateFrom, 107) + ' To ' + CONVERT(nvarchar, @DateTo, 107) 
    END 

Он не обрабатывает месяц/месяцы красиво, но он достаточно близко для того, что мне нужно для этого.

+0

Если кто-то смотрит на это для решения, измените 'THEN DATENAME (MM, @DateFrom)' выше на 'THEN DATENAME (MM, @DateFrom) + '' + DATENAME (YYYY, @DateFrom)', чтобы включить год, как это очень важно. – Dan