【问题标题】:Total Number and Total Value pl/sql总数和总值pl/sql
【发布时间】:2016-01-13 00:36:54
【问题描述】:

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

  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;

如果我在不使用光标或程序的情况下运行选择查询,我会得到以下结果:

   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

任何帮助将不胜感激

【问题讨论】:

    标签: plsql oracle11g


    【解决方案1】:

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

    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')s 转换为 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
    

    您确定在 select 和 group by 列列表中都将 trunc(..., 'mm') 添加到了列中吗?


    假设我需要遍历查询返回的每一行并通过 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;
    /
    

    【讨论】:

    • 感谢您的回答!查询给了我一个错误说:not a GROUP BY expression!!
    • 我不确定你为什么会收到这个错误,因为它对我有用(我已经用证据更新了我的答案)。您确定已将 trunc(..., 'mm') 添加到 select 和 group by 列列表中吗?
    • 它现在对我有用,谢谢,但它循环了两次匿名块已完成所有取消的数量:2 总值:39.98 所有返回的项目数:11 总值:239.89 所有返回的项目数: 11 总值:239.89
    • 您的示例代码中没有循环。另外,您参考VARCUR1;这是在哪里定义的?应该是cal_cur
    • 是的,你是对的,我用 VARCUR1 代替了 cal_cur,我的错!问题如果我在没有循环的情况下离开程序,它会给我一个条件,但是,如果我添加循环,它将循环次数以显示不必要的结果
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多