会计年度sql server

时间:2019-11-16 19:31:02

标签: sql-server function tsql fiscal

我想要一个计算会计年度的函数。会计年度必须从三月的第一个星期一开始。谢谢! 示例:

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

但是它不起作用

3 个答案:

答案 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将始终从06返回一个整数,其中0对应于星期日,而不管DateFirstLanguage的设置如何并且没有字符串操作。

将表达式调整为( @@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;