我在游标中做了一个查询,计算取消,取消或退回的项目总数和总价值。但是,我无法获得已取消,退回或全部取消的项目总数的正确值
create or replace PROCEDURE NUM_OF_RET_CAN(PRAM_DATE IN DATE)
AS
CURSOR CUR2 IS
SELECT I.CONDITION, I.DEL_DATE, SUM(DE.QUANTITY) NUMBER_OF_PRO,
SUM(NVL(DE.QUANTITY,0) * NVL (P.COSTS,0)) TOTAL
FROM ITEMS I, DE_DETAILS DE, PARTS P
WHERE DE.PRO_NO = P.PRO_NO
AND I.ITEMS_NO = DE.ITEM_NO
AND TO_CHAR(I.DEL_DATE, 'mm-yyyy') = TO_CHAR(PRAM_DATE, 'mm-yyyy')
GROUP BY I.CONDITION, I.DEL_DATE;
CAL_CUR CUR2%ROWTYPE;
BEGIN
OPEN CUR2;
FETCH CUR2 INTO CAL_CUR;
IF VARCUR1.CONDITION ='CANCELL' THEN
DBMS_OUTPUT.PUT_LINE('CANCELLED: '||CAL_CUR.NUMBER_OF_PRO );
DBMS_OUTPUT.PUT_LINE('Total: '|| CAL_CUR.TOTAL);
ELSIF VARCUR1.CONDITION ='ORDER RETURNED' THEN
DBMS_OUTPUT.PUT_LINE('RETURNED : '||
CAL_CUR.NUMBER_OF_PRO);
DBMS_OUTPUT.PUT_LINE('Total : '|| CAL_CUR.TOTAL);
ELSIF VARCUR1.CONDITION = 'ALL ORDERS ARE CANCELLED!' THEN
DBMS_OUTPUT.PUT_LINE('ALL CANCELLATIONS : '||
CAL_CUR.NUMBER_OF_PRO );
DBMS_OUTPUT.PUT_LINE('Total : '|| CAL_CUR.TOTAL);
ELSE
DBMS_OUTPUT.PUT_LINE('No records for this month');
END IF;
CLOSE CUR2;
END NUM_OF_RET_CAN;
如果我在不使用光标或程序的情况下运行select Query,我会得到这个结果:
CONDITION DEL_DATE NUMBER_OF_PRO TOTAL
------------ ------------- ------------------- ---------
ALL ORDERS ARE CANCELLED! 12-JAN-16 4 99.96
ALL ORDERS ARE CANCELLED! 10-JAN-16 2 44.98
预期答案
CONDITION DEL_DATE NUMBER_OF_PRO TOTAL
------------ ------------- ------------------- ---------
ALL ORDERS ARE CANCELLED! JAN-16 6 144.94
非常感谢任何帮助
答案 0 :(得分:0)
听起来你只需按月而不是按天分组,例如:
select i.condition,
trunc(i.del_date, 'mm') del_date,
sum(de.quantity) number_of_pro,
sum(nvl(de.quantity,0) * nvl (p.costs,0)) total
from items i
inner join de_details de on (i.items_no = de.item_no)
inner join parts p on (de.pro_no = p.pro_no)
where trunc(i.del_date, 'mm') = trunc(pram_date, 'mm')
group by i.condition,
trunc(i.del_date, 'mm');
一些注意事项:
to_char(... 'mm-yyyy')
转换为trunc(... 'mm')
因为我认为比较相同格式的列更有意义(导致更容易维护等)。我不确定为什么你会得到“不是表达式组”错误,因为它对我有用:
with items as (select 1 items_no, 'a' condition, sysdate -1 del_date from dual union all
select 2 items_no, 'a' condition, sysdate del_date from dual union all
select 3 items_no, 'a' condition, sysdate + 31 del_date from dual),
de_details as (select 1 item_no, 10 quantity, 1 pro_no from dual union all
select 2 item_no, 20 quantity, 2 pro_no from dual union all
select 3 item_no, 40 quantity, 1 pro_no from dual),
parts as (select 1 pro_no, 100 costs from dual union all
select 2 pro_no, 200 costs from dual)
----- end of mimicking your tables with data in them
select i.condition,
trunc(i.del_date, 'mm') del_date,
sum(de.quantity) number_of_pro,
sum(nvl(de.quantity,0) * nvl (p.costs,0)) total
from items i
inner join de_details de on (i.items_no = de.item_no)
inner join parts p on (de.pro_no = p.pro_no)
--where trunc(i.del_date, 'mm') = trunc(pram_date, 'mm')
group by i.condition,
trunc(i.del_date, 'mm');
CONDITION DEL_DATE NUMBER_OF_PRO TOTAL
--------- --------- ------------- ----------
a 01-JAN-16 30 5000
a 01-FEB-16 40 4000
您确定在colunn列表的select和group中将trunc(..., 'mm')
添加到了colunn吗?
以下是我编写过程的方法,假设我需要遍历查询返回的每一行并通过dbms_output显示它们:
create or replace procedure num_of_ret_can (pram_date in date)
as
cursor cur2 is
select i.condition,
trunc(i.del_date, 'mm') del_date,
sum(de.quantity) number_of_pro,
sum(nvl(de.quantity,0) * nvl (p.costs,0)) total
from items i
inner join de_details de on (i.items_no = de.item_no)
inner join parts p on (de.pro_no = p.pro_no)
where trunc(i.del_date, 'mm') = trunc(pram_date, 'mm')
group by i.condition,
trunc(i.del_date, 'mm');
v_counter number := 0;
begin
for cal_cur in cur2
loop
v_counter := v_counter + 1;
if cal_cur.condition ='CANCELL' then -- are you sure? Not CANCEL?
dbms_output.put_line('CANCELLED: '||cal_cur.number_of_pro );
dbms_output.put_line('Total: '|| cal_cur.total);
elsif cal_cur.condition ='ORDER RETURNED' then
dbms_output.put_line('RETURNED : '||cal_cur.number_of_pro);
dbms_output.put_line('Total : '||cal_cur.total);
elsif cal_cur.condition = 'ALL ORDERS ARE CANCELLED!' then
dbms_output.put_line('ALL CANCELLATIONS : '||cal_cur.number_of_pro );
dbms_output.put_line('Total : '||cal_cur.total);
end if;
end loop;
if v_counter = 0 then
dbms_output.put_line('No records for this month');
end if;
end num_of_ret_can;
/