我想要一个计算会计年度的函数。会计年度必须从三月的第一个星期一开始。谢谢! 示例:
CREATE FUNCTION dbo.fnc_FiscalYear( @AsOf DATETIME )
RETURNS INT
AS BEGIN
DECLARE @Answer INT
SET DATEFIRST 1
IF ( MONTH(@AsOf) < 3 )
or MONTH(@AsOf=3) and datename(weekday, @AsOf) = 'Monday' and datepart(day, @AsOf)>=1 and datepart(day, @AsOf)<=7;
SET @Answer = YEAR(@AsOf) - 1
ELSE SET @Answer = YEAR(@AsOf)
RETURN @Answer
END
GO
但是它不起作用
答案 0 :(得分:0)
您的脚本似乎存在许多语法错误。试试这个吧。我已经删除了SET并在if语句的位置返回。另外,请注意if语句的分组。
CREATE FUNCTION dbo.fnc_FiscalYear( @AsOf DATETIME )
RETURNS INT
AS BEGIN
DECLARE @Answer INT
IF (( MONTH(@AsOf) < 3 )
OR (MONTH(@AsOf) = 3
AND DATENAME(weekday, @AsOf) = 'Monday'
AND datepart(day, @AsOf) >= 1
AND datepart(day, @AsOf)<=7))
RETURN (YEAR(@AsOf) - 1)
RETURN YEAR(@AsOf)
END
GO
答案 1 :(得分:0)
这样做的逻辑很棘手-尤其是在三月的第一周:
CREATE FUNCTION dbo.fnc_FiscalYear (
@AsOf DATETIME
)
RETURNS INT AS
BEGIN
RETURN( CASE WHEN MONTH(@AsOf) < 3 THEN YEAR(@AsOf) - 1
WHEN MONTH(@AsOf) > 3 THEN YEAR(@AsOf)
WHEN DAY(@AsOf) >= 7 THEN YEAR(@AsOf)
WHEN DATENAME(@AsOf) = 'Monday' OR
DATENAME(@AsOf) = 'Tuesday' AND DAY(@AsOf) >= 2 OR
DATENAME(@AsOf) = 'Wednesday' AND DAY(@AsOf) >= 3 OR
DATENAME(@AsOf) = 'Thursday' AND DAY(@AsOf) >= 4 OR
DATENAME(@AsOf) = 'Friday' AND DAY(@AsOf) >= 5 OR
DATENAME(@AsOf) = 'Saturday' AND DAY(@AsOf) >= 26
THEN YEAR(@AsOf)
ELSE YEAR(@AsOf) - 1
END);
END ;
GO
答案 2 :(得分:0)
( @@DateFirst + DatePart( weekday, SampleDate ) - 1 ) % 7 + 1
将始终从0
到6
返回一个整数,其中0
对应于星期日,而不管DateFirst
或Language
的设置如何并且没有字符串操作。
将表达式调整为( @@DateFirst + DatePart( weekday, SampleDate ) - 2 ) % 7
会将循环的开始从星期日转移到星期一,将范围从0
转移到6
,从而简化了以下代码:
create function dbo.FiscalYear( @Date as Date )
returns Int
begin
return Year( @Date ) - case
when Month( @Date ) <= 2 then 1 -- January and February are always part of the prior year.
-- In March it is the prior year only in the first week and if the calculated
-- DoW is less than the day of the month.
when Month( @Date ) = 3 and Day( @Date ) < 7 and
( @@DateFirst + DatePart( weekday, @Date ) - 2 ) % 7 >= Day( @Date ) then 1
else 0 end;
end;
使用示例数据测试该功能:
with
-- Generate sample dates for 20 years.
YearOffsets as (
select 0 as YearOffset
union all
select YearOffset + 1
from YearOffsets
where YearOffset < 20 ),
SampleDates as (
select Cast( DateAdd( year, YearOffset, '2000-02-28' ) as Date ) as SampleDate, 1 as Counter
from YearOffsets
union all
select DateAdd( day, 1, SampleDate ), Counter + 1
from SampleDates
where Counter < 10 )
-- Calculate the Fiscal Year for each sample date.
select SampleDate, DateName( weekday, SampleDate ) as WeekDay,
( @@DateFirst + DatePart( weekday, SampleDate ) - 2 ) % 7 as DayOfWeek, -- 0 = Monday.
dbo.FiscalYear( SampleDate ) as FiscalYear
from SampleDates
order by SampleDate;