从varchar年份和日期参数格式“2016-11”

时间:2017-02-15 00:00:27

标签: sql sql-server sql-server-2008 tsql ssms

我有一个包含reportyear和reportmonth列的表。对于reportyear,该列是vharchar(4),等于2016年格式。对于reportmonth,它是一个varchar(2),具有01,02,03等格式。我有一个数据参数连接这两个,因为我们的最终用户想要一个下拉日期。所以我的参数是@ReportDate varchar(7)。

我的问题是我的存储过程中的一个选择,我需要将where子句放回一个月。因此,如果我的参数等于'2016-11',我想要一个where子句,它返回'2016-10'。我使用流动的查询成功完成了这个:

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

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

2 个答案:

答案 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

答案 1 :(得分: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是一个字符串。