Plsql pl/sql的总数和总值

Plsql pl/sql的总数和总值,plsql,oracle11g,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, S

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

  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查询,则会得到以下结果:

   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

任何帮助都将不胜感激

听起来你只需要按月分组,而不是按天分组,例如:

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表的别名,所以我相应地更新了它
  • 我已经将您的
    转换为_char(…'mm yyyy')
    s转换为
    trunc(…'mm')
    ,因为我认为以定义的相同格式比较列更有意义(导致更容易维护等)


我不知道为什么会出现“not a group by expression”错误,因为它对我有效:

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
是否确实已将
trunc(…,'mm')
添加到select和group by colunn列表中的colunn


下面是我编写过程的方式,假设我需要循环查询返回的每一行,并通过dbms_输出显示它们:

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;
/

谢谢你的回答!查询给了我一个错误,它说:不是一个groupby表达式!!我不知道你为什么会犯这样的错误,因为它对我有效(我已经用证据更新了我的答案)。您确定已将
trunc(…,'mm')
添加到“选择”和“按列分组”列表中吗?它现在对我有效,谢谢,但它会循环两次匿名块完成的所有取消数:2总值:39.98所有项目返回数:11总值:239.89所有项目返回数:11总值:239.89示例代码中没有循环。此外,还可以参考
VARCUR1
;这个定义在哪里?那应该是
cal\u cur
?是的,你是对的,我把VARCUR1改为cal\u cur,我的错!问题是,如果我不使用循环,它会给我一个条件,但是,如果我添加循环,它会循环多次以显示不必要的结果