我正在使用表格EQUIP,其中包含10M +行。虽然查询在几秒钟内执行,但运行for循环需要数小时。我觉得效率很低。它基本上采用与给定条件匹配的行的总和。请给我一个有效的方法来运行它。我为EXIPMNT创建了索引(mch_code,contract,CRE_DATE)
我需要分别得到每个M,P,T,X,E,D的总和
CURSOR get_cost_ IS
SELECT EQUIP, COST
FROM EXIPMNT
WHERE mch_code = mch_code_
AND contract = contract_
AND CRE_DATE BETWEEN TO_DATE('01/01/' || year_, 'DD/MM/YYYY')
AND TO_DATE('01/01/' || year_, 'DD/MM/YYYY') + INTERVAL '1' YEAR;
BEGIN
FOR rec_ IN get_cost_ LOOP
IF (rec_. EQUIP = 'M') THEN
material_ := material_ + nvl(rec_.cost, 0);
ELSIF (rec_. EQUIP = 'P') THEN
personal_ := personal_ + nvl(rec_.cost, 0);
ELSIF (rec_. EQUIP = 'T') THEN
tool_facility_ := tool_facility_ + nvl(rec_.cost, 0);
ELSIF (rec_. EQUIP = 'X') THEN
expense_ := expense_ + nvl(rec_.cost, 0);
ELSIF (rec_. EQUIP = 'E') THEN
external_ := external_ + nvl(rec_.cost, 0);
ELSIF (rec_. EQUIP = 'D') THEN
direct_sales_ := direct_sales_ + nvl(rec_.cost, 0);
END IF;
NULL;
END LOOP;
total_cost_ := material_ + personal_ + tool_facility_ + expense_ + external_ + direct_sales_;
答案 0 :(得分:2)
如果你真的只是在具有指定值的所有行的总和之后,那么这应该可以解决问题:
select sum(cost)
from exipmnt
where mch_code = mch_code_
and contract = contract_
and cre_date >= TO_DATE('01/01/' || year_, 'DD/MM/YYYY')
and cre_date < TO_DATE('01/01/' || year_, 'DD/MM/YYYY') + INTERVAL '1' YEAR
and equip in ('M', 'P', 'T', 'X', 'E', 'D');
否则,您可能会寻找以下其他方式:
在不同的行中显示每个装备值的总数(第三列显示所有行的完整总数:
select equip,
sum(cost),
sum(sum(cost)) over () total_cost
from exipmnt
where mch_code = mch_code_
and contract = contract_
and cre_date >= TO_DATE('01/01/' || year_, 'DD/MM/YYYY')
and cre_date < TO_DATE('01/01/' || year_, 'DD/MM/YYYY') + INTERVAL '1' YEAR
and equip in ('M', 'P', 'T', 'X', 'E', 'D')
group by equip;
将行转换为11g格式的列:
select sum(case when equip = 'M' then cost end) material_total,
sum(case when equip = 'P' then cost end) personal_total,
sum(case when equip = 'T' then cost end) tool_facility_total,
sum(case when equip = 'X' then cost end) expense_total,
sum(case when equip = 'E' then cost end) external_total,
sum(case when equip = 'D' then cost end) direct_sales_total,
sum(cost) total
from exipmnt
where mch_code = mch_code_
and contract = contract_
and cre_date >= TO_DATE('01/01/' || year_, 'DD/MM/YYYY')
and cre_date < TO_DATE('01/01/' || year_, 'DD/MM/YYYY') + INTERVAL '1' YEAR
and equip in ('M', 'P', 'T', 'X', 'E', 'D');
透视行11g样式:
select material_total,
personal_total,
tool_facility_total,
expense_total,
external_total,
direct_sales_total,
nvl(material_total, 0)
+ nvl(personal_total, 0)
+ nvl(tool_facility_total, 0)
+ nvl(expense_total, 0)
+ nvl(external_total, 0)
+ nvl(direct_sales_total, 0) total
from (select *
from exipmnt
where mch_code = mch_code_
and contract = contract_
and cre_date >= TO_DATE('01/01/' || year_, 'DD/MM/YYYY')
and cre_date < TO_DATE('01/01/' || year_, 'DD/MM/YYYY') + INTERVAL '1' YEAR
and equip in ('M', 'P', 'T', 'X', 'E', 'D'))
pivot (sum(cost) as total for equip in ('M' as material,
'P' as personal,
'T' as tool_facility,
'X' as expense,
'E' as external,
'D' as direct_sales));