一、问题描述
财务结账周期是上月26号到本月的25号,比如 2020-01-26 00:00:00 到 2020-02-25 23:59:59
现在要求2020年的大于1月26到2月01之间的数据,在报表中显示2月的财务月份,其他同事说有函数,我也没找,
写了个case when ,这样写的弊端就是执行效率有点慢
--case when的思路是
if 31>=dd>=26 then
mm=mm+1
if mm=13(跨年) then
mm=01
yyyy=yyyy+1
else
yyyy=yyyy
end if
else
mm=mm
yyyy=yyyy
end if;
输出yyyy-mm
实际数据 呈现数据
2019-12-23 2019-12
2019-12-24 2019-12
2019-12-25 2019-12
2019-12-26 2020-01
2019-12-27 2020-01
2019-12-28 2020-01
2019-12-29 2020-01
2019-12-30 2020-01
2019-12-31 2020-01
2020-01-01 2020-01
................
2020-01-25 2020-01
2020-01-26 2020-02
2020-01-27 2020-02
1.Oracle写法:
SELECT
case
when to_char(a.CONFIRM_TIME, 'dd') in
('26', '27', '28', '29', '30', '31') then
(case lpad(to_char(to_number(to_char(a.CONFIRM_TIME, 'mm')) + 1), 2, '0')
when '13' then
to_char(to_number(to_char(a.CONFIRM_TIME, 'yyyy')) + 1)
else
to_char(a.CONFIRM_TIME, 'yyyy')
end) ||
(case lpad(to_char(to_number(to_char(a.CONFIRM_TIME, 'mm')) + 1), 2, '0')
when '13' then
'01'
else
lpad(to_char(to_number(to_char(a.CONFIRM_TIME, 'mm')) + 1), 2, '0')
end)
else
to_char(a.CONFIRM_TIME, 'yyyy') || to_char(a.CONFIRM_TIME, 'mm')
end as year_month
from view_zy_detail_charge_b a
2.sql sever 写法
SELECT
case when datename(dd,a.confirm_time) in
('26', '27', '28', '29', '30', '31') then
(case dbo.lpad(datename(mm,a.confirm_time) + 1,2,'0')
when '13' then
convert(varchar(10),datename(yyyy,a.confirm_time) + 1)
else
convert(varchar(10),datename(yyyy,a.confirm_time))
end)
+
(case dbo.lpad(datename(mm,a.confirm_time) + 1,2,'0')
when '13' then '01' else dbo.lpad(datename(mm,a.confirm_time) + 1,2,'0') end)
else
convert(varchar(10),datename(yyyy,a.confirm_time)) + convert(varchar(10),datename(mm,a.confirm_time))
end as year_month
from view_zy_detail_charge_b a
注意的点:
sqlsever 的拼接用到的“+”,导致了有可能与加减用的“+” 区别不开,尤其是类似数字的拼接的时候 ,
datename()虽然返回的是字符窜但是可以直接用数字加减,所以每一个得到的数字都用convert()转一下
sql sever没有lpad(),这个函数是自己写的,作用与Oracle的lpad相同
上面的sql应该可以精简
来源:https://www.cnblogs.com/thomasbc/p/12456347.html