I am trying to create a calendar in Oracle PL/SQL, I need two calendars: Fiscal year calendar and normal calendar. I have created them using the code:
Fiscal year calendar:
WITH dts AS (SELECT TRUNC(to_date('&year', 'yyyy'), 'yyyy') + LEVEL + 181 AS dt
FROM dual
CONNECT BY LEVEL <= to_char(TO_DATE(&YEAR || '1231', 'yyyymmdd'), 'ddd')),
-- dt_mon AS (SELECT '7' from dual),
dts2 AS (SELECT dt,
TRUNC(dt, 'mm') dt_mon,
TRUNC(dt, 'iw') dt_start_of_week,
to_char(dt, 'fmdd') day_of_month
FROM dts)
SELECT to_char(dt_mon, 'fmMonth') "MONTH",
row_number() OVER (PARTITION BY to_char(dt_mon, 'fmMonth') ORDER BY dt_start_of_week) week_num,
MAX(CASE WHEN dt = dt_start_of_week THEN day_of_month END) mon,
MAX(CASE WHEN dt = dt_start_of_week + 1 THEN day_of_month END) tue,
MAX(CASE WHEN dt = dt_start_of_week + 2 THEN day_of_month END) wed,
MAX(CASE WHEN dt = dt_start_of_week + 3 THEN day_of_month END) thu,
MAX(CASE WHEN dt = dt_start_of_week + 4 THEN day_of_month END) fri,
MAX(CASE WHEN dt = dt_start_of_week + 5 THEN day_of_month END) sat,
MAX(CASE WHEN dt = dt_start_of_week + 6 THEN day_of_month END) sun
FROM dts2
GROUP BY dt_mon,
to_char(dt_mon, 'fmMonth'),
dt_start_of_week
ORDER BY dt_mon, dt_start_of_week;
In my query, if I want to specify the fiscal year calendar, how can I do that? How to create a table with this calendar to refer in queries and If I want to store timeseries data, is there any provision in Oracle? Any help here would be appreciated. Thank you!!
Not really because the definition of a "fiscal" year is totally at the whim of the organization that uses it.
I've worked for places where the fiscal year starts in April, others in July. Similarly, I've worked at places where the fiscal week starts on Monday, others on a Friday. I've even worked at places where the number of days in certain fiscal weeks changes from year to year, because the first day of the year starts on a different day, so they crammed an "8th day" into a week for business reporting.
There is no single "fiscal" year. Ultimately, most places do you what you've done above, namely have a table that stores the true calendar, its mapping to that company's fiscal calendar and use it (typically) as dimension table for reporting.
For example, here's an (anonymised) snippet from a client I worked with....
CREATE TABLE DATE_REPORTING
(
,CAL_DATE DATE NOT NULL
,CAL_MONTH_START DATE NOT NULL
,CAL_MONTH_END DATE NOT NULL
,CAL_MONTH_OF_YEAR NUMBER(2) NOT NULL
,CAL_MONTH_OF_FIN_YEAR NUMBER(2) NOT NULL
,CAL_MONTH_NAME_ABBR VARCHAR2(3) NOT NULL
,CAL_MONTH_NAME VARCHAR2(20) NOT NULL
,CAL_QTR_START DATE NOT NULL
,CAL_QTR_END DATE NOT NULL
,CAL_YEAR NUMBER(4) NOT NULL
,CAL_DAY_OF_MONTH NUMBER(3) NOT NULL
--
,DAY_OF_WEEK_ABBR VARCHAR2(3) NOT NULL
,DAY_OF_WEEK VARCHAR2(10) NOT NULL
,FIN_DAY_OF_WEEK NUMBER(2) NOT NULL
--
,FIN_WEEK_OF_MONTH NUMBER(2) NOT NULL
,FIN_WEEK_OF_YEAR NUMBER(2) NOT NULL
,FIN_WEEK_START DATE NOT NULL
,FIN_WEEK_END DATE NOT NULL
,FIN_SETTLEMENT_PERIOD_SEQ NUMBER(10)
--
,FIN_MONTH_NAME VARCHAR2(10) NOT NULL
,FIN_MONTH_NAME_ABBR VARCHAR2(3) NOT NULL
,FIN_MONTH_OF_YEAR NUMBER(2) NOT NULL
,FIN_MONTH_START DATE NOT NULL
,FIN_MONTH_END DATE NOT NULL
,FIN_MONTH_WEEKS NUMBER NOT NULL
--
,FIN_QTR_START DATE NOT NULL
,FIN_QTR_END DATE NOT NULL
--
,FIN_YEAR NUMBER(4) NOT NULL
,FIN_YEAR_NAME VARCHAR2(8) NOT NULL
,FIN_YEAR_START DATE NOT NULL
,FIN_YEAR_END DATE NOT NULL
...
...
...