create or replace function fiscal_year_start_date(p_date date) return date
as
pragma udf;
begin
return add_months(trunc(add_months(p_date,3),'YYYY'), -3);
end;
/
alter session set nls_date_format='YYYY-MM-DD';
select fiscal_year_start_date(date'2016-01-01') from dual;
FISCAL_YEA
----------
2015-10-01
-- should be 2012
SELECT (EXTRACT (YEAR FROM ADD_MONTHS (DATE '2013-09-30', -9))||'-10-01') from dual;
-- should be 2013
SELECT (EXTRACT (YEAR FROM ADD_MONTHS (DATE '2013-10-01', -9))||'-10-01') from dual;
-- should be 2018
SELECT (EXTRACT (YEAR FROM ADD_MONTHS (SYSDATE, -9))||'-10-01') from dual;
如果您需要一个不需要您为每年编写逻辑的更动态的函数,您可以使用下面的 CASE WHEN 语句,该语句适用于给定 FY 的任何年份(在这个 10 月 1 日是 FY 的开始)。本质上,它读取日期字段的月份,如果它是从一月到九月,那么它会从日期字段中提取年份并创建一个新的 FY 变量。如果月份是从 10 月到 12 月,则需要年份并加 1。显然这个逻辑可以针对具体组织的业务定义来调整他们如何定义FY,但是希望你能理解这个逻辑。
CASE
WHEN EXTRACT(MONTH FROM k.date_var) BETWEEN 10 AND 12 THEN EXTRACT(YEAR FROM date_var) +1
WHEN EXTRACT(MONTH FROM k.date_var) BETWEEN 1 AND 9 THEN EXTRACT(YEAR FROM k.date_var)
ELSE NULL
END AS FY_CONCLUDED,
pragma_udf
是可选的,它是一个 12c 特性,当在普通 SQL 中使用时,可以稍微提高此类用户定义函数的性能(但在 PL/SQL 中可能会降低)。很多方法可以做到这一点。但这里有一个:
只需要一个
TO_DATE()
.小提琴链接。
如果您需要一个不需要您为每年编写逻辑的更动态的函数,您可以使用下面的 CASE WHEN 语句,该语句适用于给定 FY 的任何年份(在这个 10 月 1 日是 FY 的开始)。本质上,它读取日期字段的月份,如果它是从一月到九月,那么它会从日期字段中提取年份并创建一个新的 FY 变量。如果月份是从 10 月到 12 月,则需要年份并加 1。显然这个逻辑可以针对具体组织的业务定义来调整他们如何定义FY,但是希望你能理解这个逻辑。