T-SQL寻找最简洁的方法来总结开始和结束日期范围

时间:2015-04-06 16:56:55

标签: sql-server datetime

真的很长一点,我在一个表中有两个日期时间字段,我将其加载到变量@DateFrom和@DateTo中,我需要“解释”它们在文本中覆盖的范围,以便在屏幕上显示。虽然字段是datetime,但时间组件将被忽略。我也声明@Current是一个日期时间来保存getDate()的结果,以防我需要在比较之前剥掉时间。

由于这种事情并非罕见,我希望以前有人这样做过。

一些例子(我将使用今天2015年4月6日的@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).

我希望有人发布了函数或存储过程的代码来执行此操作或在某处非常相似,因此我不必重新发明轮子。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

我不知道已经构建的函数或sproc,但Pinal Dave的网站上有一些东西可以复制粘贴并准备好80%的函数:http://blog.sqlauthority.com/2008/08/29/sql-server-few-useful-datetime-functions-to-find-specific-dates/

答案 2 :(得分: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

它没有很好地处理月份/月份,但它足够接近我需要它做的事情。