总数和总价值pl / sql

时间:2016-01-12 13:52:50

标签: plsql oracle11g

我在游标中做了一个查询,计算取消,取消或退回的项目总数和总价值。但是,我无法获得已取消,退回或全部取消的项目总数的正确值

  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

非常感谢任何帮助

1 个答案:

答案 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');

一些注意事项:

  • 您会注意到我已将旧式连接转换为ANSI连接语法。
  • 您将items表别名为“pros”,但在查询的其他位置,别名“i”被引用。我相信这是items表的别名应该是什么,所以我相应地更新了它。
  • 我已将您的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;
/