【问题标题】:fiscal year sql server会计年度sql server
【发布时间】:2019-11-16 19:31:02
【问题描述】:

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

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

但它不起作用

【问题讨论】:

  • “不工作”是什么意思?
  • 欢迎来到堆栈,正如 Sergio 所指出的,具体说明“不起作用”是很重要的。请提供尽可能多的信息。

标签: sql-server function tsql fiscal


【解决方案1】:

您的脚本似乎存在许多语法错误。试试这个。我已经删除了 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

【讨论】:

  • 对于 2019-03-04,该函数返回 2018。对于 2019-03-02 和 2019-03-04,它返回 2019。看起来不对。
【解决方案2】:

这个逻辑很棘手——尤其是在 3 月的第一周:

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

【讨论】:

    【解决方案3】:

    ( @@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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-04
      • 2013-07-06
      • 1970-01-01
      • 1970-01-01
      • 2016-05-04
      • 2019-03-08
      • 1970-01-01
      • 2016-04-05
      相关资源
      最近更新 更多