2017-02-15 88 views
-1

我有一个表有列reportyear和reportmonth。对于reportyear,该列是一个vharchar(4),等于2016年格式。对于reportmonth,它是一个具有01,02,03等格式的varchar(2)。由于我们的最终用户需要一个下拉日期,因此我有一个数据参数将两者连接起来。所以我的参数是@ReportDate varchar(7)。从varchar年份和日期参数格式'2016-11'减去月份

我的问题是我的存储过程中的一个选择,我需要把where子句放回去一个月。所以如果我的参数等于'2016-11',我想要一个where子句,它返回'2016-10'。我已经成功地做到了这一点利用流动查询:

SUBSTRING(@Reportdate, 1, 4) + '-' + cast(substring(@ReportDate, 6, 7) -1 as varchar(20)) 

这将返回“2016-10”如果我选择“2016-11”的任何报告日期参数。 但经过进一步的思考,如果我的报告日期是一月份,这是行不通的,因为上面的查询只是字面上减去一个字符串值。所以如果我选择'2016-01',上面的查询将返回'2016-0'。

回答

0

例如:

Declare @Reportdate varchar(7) = '2016-01' 

Select AsDate = dateadd(MM,-1,@ReportDate+'-01') 
     ,AsSting = left(convert(date,dateadd(MM,-1,@ReportDate+'-01'),101),7) 

返回

AsDate  AsSting 
2015-12-01 2015-12 
+0

最终用户希望SSRS中的下拉参数为破折号,这就是为什么我声明它为varchar(7)以包含破折号@John Cappelletti – Lisbon

+0

@Lisbon我更新了包含破折号,当我看到评论。 varchar(7)vs varchar(10)不是问题 –

0

你可以用case

select concat(@ReportYear - 1, 
       (case when @ReportMonth = '01' then '12' 
        else right(concat('0', @ReportMonth - 1)) 
       end) 
      ) 

的SQL Server将把字符串作为整数 - 不经过任何转换错误为您的价值。然后concat()将它们转换回字符串。

编辑:

我看,这是倒退。让我们添加一个在表中的列,并比较@Report_Month

where (reportmonth = 12 and 
     right(@ReportDate, 2) = '01' and left(@Report_date, 4) = reportyear + 1 
    ) or 
     (left(@ReportDate, 4) = reportyear and 
     right(@ReportDate, 2) = reportmonth + 1 
    ) 

但考虑这之后,我认为你应该使用一个计算列:

alter table t add reportdate as (datefromparts(reportyear, reportmonth, 1)); 

后来干脆:

where dateadd(month, 1, reportdate) = cast(@reportdate + '01' as date) 

当然,你可以做明确的比较:

where (dateadd(month, 1, datefromparts(reportyear, reportmonth, 1)) = 
     cast(@reportdate + '01' as date) 
    ) 

请注意,这两个都假定@reportdate是一个字符串。

+0

我的参数是atReportDate,它是Reportyear和reportmonth列的串联。因此,在我的where子句中,我将它定义为: where reportyear +' - '+ reportmonth = @ReportDate(ReportDate is'2016-11') – Lisbon