评论
首先介绍一下您的代码:
没有理由在这些分配中使用select。第二种形式就是你所需要的,所有额外的噪音和括号的嵌套都没有帮助。在某些情况下,您确实需要子查询,但不是简单的表达式。
-- bad
set @StartMonth = (select month('2014-'+substring(ltrim(rtrim(@Qmonth)),1,3)+'-01') as mnth1)
-- better
set @StartMonth = month('2014-' + substring(ltrim(rtrim(@Qmonth)), 1, 3) + '-01')
出于我不确定的原因,您开始使用 select 语法。但请注意,您可以说select <result> = <expr> 或select <expr> as <result>。 as 完全是可选的,但强烈推荐。
-- error
select from_dt as (select DATEADD(month,@StartMonth-1,DATEADD(year,@ac_year-1900,0)))
-- ok
select DATEADD(month, @StartMonth-1, DATEADD(year, cast(@ac_year-1900 as int), 0)) as from_dt
还有另一个错误,您尝试使用字符串/字符值进行减法运算。我想我的想法更接近你的想法,但我不保证那行代码会是完全正确的。
接下来,你的论点在另一个 sn-p 中被取消了。我相信您希望在第二个set 的第四个位置有 3 个字符。 Substring() 的第三个参数需要是字符长度而不是结束位置。所以使用4, 3 而不是5, 7。
-- wrong part of the date
set @Endmonth =(select month('2014-'+substring(ltrim(rtrim(@Qmonth)),5,7)+'-01') as month2)
-- correct part of the date
set @Endmonth = month('2014-' + substring(ltrim(rtrim(@Qmonth)), 4, 3) + '-01')
这些更改应该让您回到正确的轨道上,尽管您还没有达到必须找到季度末的一个月的最后一天的地步。我会继续提供我自己的方法。
工作代码
declare @q int =
set @q = /* ignoring everything after the first three characters */
case lower(substring(@QMonth, 1, 3))
when 'jan' then 0 when 'apr' then 1 when 'jul' then 2 when 'oct' then 3
end;
declare @y int;
set @y = cast(left(@ac_year, 4) as int); /* assuming this contains a value like '2014-15' */
set @StartMonth = dateadd(quarter, @q, dateadd(year, @y - 2000, '2000-01-01');
set @EndMonth = dateadd(day, -1, dateadd(quarter, 1, @StartMonth));
您将需要查看输出参数以获取实际返回两个日期值的过程。我会让你自己处理。