SQL - 重写基于日期的查询而不进行字符串操作?

时间:2013-01-03 18:51:18

标签: sql tsql datetime sql-server-2008-r2

我有一个在SQL 2008 R2服务器上运行的SQL查询。它运行在每月的1日和16日。该查询包含以下用于设置StartDate和EndDate参数的逻辑:

DECLARE     @RunDateTime datetime
DECLARE     @RunDate datetime
DECLARE     @StartDate datetime
DECLARE     @EndDate datetime
DECLARE     @Month int
DECLARE     @Year int
DECLARE     @strStartDate varchar(10)

SET     @RunDateTime = GetDate()
SET     @RunDate = CAST(@RunDateTime AS DATE)

IF                  DATEPART(d, @RunDate) = 16
    BEGIN       
                    SET @StartDate =  DATEADD(d, -15, @RunDate)
                    SET @EndDate = @RunDate
    END
ELSE
    BEGIN
                    IF      Month(@RunDate) = 1
                            SET @Month = 12
                    ELSE    
                            SET @Month = Month(@RunDate) - 1

                    IF      Month(@RunDate) = 1
                            SET @Year = Year(@RunDate) - 1
                    ELSE
                            SET @Year = Year(@RunDate)

                    SET @strStartDate = CAST(@Year AS VARCHAR) + CAST(@Month AS VARCHAR) + '16'
                    SET @StartDate = CONVERT(datetime, @strStartDate)
                    SET @EndDate = @RunDate
    END

如果查询在16日运行,我们希望日期范围是从该月的第1天到第15天。如果查询是在1日运行的,我们希望日期范围是从上个月的第16个到上个月结束。

由于工作需求的变化,我们被告知我们需要找到一种方法来实现这一点,而无需使用任何日期转换为字符串。这是可能的,有没有人知道如何做到这一点?我很快就离开了这里。

3 个答案:

答案 0 :(得分:2)

当我看到你之前的问题时,我知道有一种更简单的方法可以解决这个问题。怎么样:

DECLARE     @StartDate date;
DECLARE     @EndDate date;
DECLARE     @RunDateTime datetime = getdate() - 2;

if DAY(@RunDateTime) = 1
begin
    set @StartDate = dateadd(day, 15, DATEADD(MONTH, -1, @RunDateTime));
    set @EndDate = DATEADD(day, -1, @RunDateTime);
end
else if day(@RunDateTime) = 16
begin
    set @StartDate = dateadd(day, -DAY(@RunDateTime) + 1, @RunDateTime);
    set @EndDate = dateadd(day, -DAY(@RunDateTime) + 15, @RunDateTime);
end
else -- do your error processing here

答案 1 :(得分:1)

试试这个(SQL FIDDLE);

declare @startdate date, @enddate date, @runDate date
select @runDate = '20130216'

select @startdate = case datepart(day,@runDate) when 16 
                         then dateadd(day,-15, @runDate)
                         else dateadd(day,14, dateadd(month,-1,@runDate))
                    end,
       @enddate =  dateadd(day,-1,@runDate)

select @startdate, @enddate 
--Results for when @runDate = '20130216'
2013-02-01  2013-02-15

--Results for when @runDate = '20130201'
2013-01-15  2013-01-31

答案 2 :(得分:0)

这样的事情可能有用:

where
    Run_Date between
    (
        case
            when datepart(dd, getdate()) = 1 then dateadd(mm, -1, getdate())
            else dateadd(dd, -15, getdate())
        end
    )
    and
    (
        case
            when datepart(dd, getdate()) = 1 then dateadd(dd, -1, getdate())
            else dateadd(dd, -1, getdate())
        end
    )

您的电话号码可能会有所不同