我有一个表per_all_peopl_f,其中包含以下列:
name person_id emp_flag effective_start_date effective_end_date DOJ
--------------------------------------------------------------------------------
ABC 123 Y 30-MAR-2011 30-MAR-2013 10-FEB-2011
ABC 123 Y 24-FEB-2011 27-FEB-2011 10-FEB-2011
DEF 345 N 10-APR-2012 30-DEC-4712 15-SEP-2011
有许多条目(1000+)包含重复数据和不同的有效开始日期。
我必须计算劳动力人数。也就是说,每季度退出公司的员工人数。
必须提取以下列:
我过去常常查找人数的查询是:
功能1:
CREATE OR REPLACE FUNCTION function_name
(l_end_date ,l_start_date )
RETURN number;
IS
l_emp
BEGIN
select count(distinct papf.person_id)
into l_emp
from per_all_people_f papf
where papf.emp_flag ='Y'
and effective_start_date >=l_end_date
and effective_end_date <=l_start_date ;
return l_emp;
END function_name;
主要包裹:
create xx_pack_name body
is
cursor cur_var
is
select function_name('01-MAR-2012','31-MAY-2012') EMP_2012,
function_name('01-MAR-2013','31-MAY-2013') EMP_2013,
function_name('01-MAR-2012','31-MAY-2012')-function_name('01-MAR-2013','31-MAY-2013') Diff
from dual;
end xx_pack_name ;
这是否具有成本效益?
答案 0 :(得分:0)
如果effective_start_date
表的至少effective_end_date
和per_all_people_f
字段都有索引,则似乎是一个很好的变体。
此查询的理想变体是
create index x_per_all_people_search on per_all_people_f(
effective_start_date,
effective_end_date,
person_id,
emp_flag
)
但维护成本太高(磁盘成本,插入速度)。
此外,包体中的游标必须包含子查询并重用函数调用结果:
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
);
当然,最好的解决方案是最小化上下文切换并从单个SQL查询中获取所有值。此外,您可以直接向光标提供参数:
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
);
从我的观点来看,函数/游标参数过于通用,可能更好的创建一个包装器,它将输入参数作为季度数和两年进行比较。
最后,如果计划在PL / SQL中使用的结果(我想由于返回单行)不使用游标,只需通过输出参数返回计算值。从另一个角度来看,如果你需要在一个光标中获得全年的季度数据,那么计算所有季度并在单个查询中进行比较可能更有效。