I have one table, per_all_peopl_f, with following columns:
name person_id emp_flag effective_start_date effective_end_date DOJ
---------------------------
Seems to be a good variant in case if there are index on at least effective_start_date
and effective_end_date
fields of per_all_people_f
table.
Ideal variant for this query is
create index x_per_all_people_search on per_all_people_f(
effective_start_date,
effective_end_date,
person_id,
emp_flag
)
but it may be too expensive to maintain (disk cost, insertion speed).
Also, cursor in package body must contain subquery and reuse function call results:
cursor cur_var
is
select
EMP_2012,
EMP_2013,
(EMP_2013 - EMP_2012) Diff
from (
select
function_name('01-MAR-2012','31-MAY-2012') EMP_2012,
function_name('01-MAR-2013','31-MAY-2013') EMP_2013
from dual
);
Of course best solution is to minimize context switches and get all values from single SQL query. Also, you can supply parameters directly to cursor:
cursor cur_var(
start_1 date, end_1 date,
start_2 date, end_2 date
)
is
select
EMP_2012,
EMP_2013,
(EMP_2013 - EMP_2012) Diff
from (
select
(
select
count(distinct papf.person_id)
from
per_all_people_f papf
where
papf.emp_flag = 'Y'
and
effective_start_date >= trunc(start_1)
and
effective_end_date <= trunc(end_1)
) EMP_2012,
(
select
count(distinct papf.person_id)
from
per_all_people_f papf
where
papf.emp_flag = 'Y'
and
effective_start_date >= trunc(start_2)
and
effective_end_date <= trunc(end_2)
) EMP_2013
from dual
);
From my point of view function/cursor parameters is too generic, may be better to create a wrapper which takes as input parameters quarter number and two years to compare.
And last, if results planned to be used in PL/SQL (I suppose that because of returning a single row) don't use cursor at all, just return calculated values through output parameters. From another point of view if you need to get quarter data for full year in one cursor it may be more efficient to count all quarters and compare it in single query.