PLSQL сравнивает и присваивает значения на основе MAX stockcount - PullRequest
0 голосов
/ 19 сентября 2019

У меня есть требование назначить номера GRP магазинам с суммой (stockcount) только до значения 110000, как описано на рисунке.Означает, что номера GRP увеличиваются на 1, как только сумма складских запасов достигает или пересекает 110000, после чего выделяются следующие номера запасов.

См. Изображение ниже.

Складской запас Максимальное количество этот код, похоже, не соответствует тому, что нужно.

SET ECHO OFF
SET FEEDBACK ON
SET TIMING ON
SET SERVEROUTPUT ON SIZE 1000000
SET LINESIZE 200
SET PAGESIZE 0
SET VERIFY OFF

VARIABLE return_code NUMBER

DECLARE

   v_pg        sku.u_pg%TYPE;
   v_count     NUMBER := 0;
   v_aggcount  NUMBER := 0;
   v_value     NUMBER := 1;

   CURSOR cur_upd_optinv_label
   IS
      SELECT /*+ Parallel (64) */ 
            LOCATION, 
            count(*) as STOCK_COUNT
        FROM sku 
        GROUP BY LOCATION 
        order by count(*) desc;

BEGIN

   BEGIN

      FOR vll_use IN cur_upd_optinv_label

      LOOP
         v_pg := vll_use.LOCATION;
         v_count := vll_use.stockcount;
         v_aggcount := v_aggcount + v_count;

         IF v_aggcount <= 110000

         THEN

            UPDATE the GRP column  = v_value where location = v_pg;

        ELSE

            v_value := v_value + 1;

            UPDATE the GRP column  = v_value where location = v_pg;

            v_aggcount := v_count;

      EXIT WHEN v_aggcount = 11;
      END IF;
      END LOOP;
   EXCEPTION
      WHEN OTHERS
      THEN
         RAISE;
   END;

COMMIT;
   :return_code := 0;

EXCEPTION
   WHEN OTHERS
   THEN
      :return_code := 3;
ROLLBACK;
      DBMS_OUTPUT.put_line (
         'Error encountered: ' || SQLCODE || ' ' || SQLERRM);
END;
/

EXIT :return_code

Ответы [ 2 ]

0 голосов
/ 21 сентября 2019

Ответ @srinu nivas может быть удовлетворительным, но есть 2 проблемы: Условие if (l_agg_cnt <= 110000 или l_agg_cnt> = 110000) всегда будет возвращать True (если l_agg_cnt не равен нулю).Также там курсор предполагает, что есть одна строка для каждого местоположения.Это, однако, не ясно из описания.Чего не хватает, вы бы хорошо сделали обзор раздела справки How_to_Ask .

Хотя PL / SQL в целом способен, лучше позволить SQL выполнять тяжелую работу - как можно большую часть работы.В этом случае возможно одно утверждение.Он объединяет слияние с рекурсивным CTE.(Примечание. Для каждого местоположения не требуется отдельной строки.)

merge into sku
using (with loc  as
          --- get location and total stock count ordering by total and gererate id 
          ( select location, stock_count, rownum row_id 
              from (select location, stock_count  
                      from (select location, sum(stock_count) stock_count
                              from sku 
                             group by location
                           )   
                      order by stock_count desc
                   )
           )  
         -- Build recursive CTE 
         , grp (location,stock_count,group_count,grp,row_id ) as
                  --  Starting with id =1 from loc cte above and setting grp = 1
               ( select location,stock_count,stock_count,1,row_id
                   from loc  
                  where row_id = 1
                  -- now join each row 2-n from loc above and determining total stock for the group and assigning grp 
                 union all 
                 select loc.location,loc.stock_count
                        -- update grp and reset group total stock
                      , case when grp.group_count > 110000 then loc.stock_count else  grp.group_count + loc.stock_count end        
                      , case when grp.group_count > 110000 then grp.grp+1 else grp.grp end
                      , loc.row_id
                   from grp join loc on grp.row_id+1 = loc.row_id 
               ) 
               -- finally extract location and its assigned group
               select location, grp from grp) grp_set

      -- identify location and set grp (note updates all rows for location)
      on (grp_set.location = sku.location)
      when matched then
           update set grp = grp_set.grp;

--- Результаты
выберите отдельное местоположение, stock_count, grp, sum (stock_count) over (разбиение по grp) из(выберите местоположение, grp, sum (stock_count) stock_count из sku, где grp не является нулевым, сгруппируйте по местоположению, grp) упорядочите по grp, location

;

К сожалению, я не смог проверить ваши данные, поскольку они не были представлены в виде текста.Удачи

0 голосов
/ 19 сентября 2019

Я надеюсь, что это может помочь вам.

declare 
l_val number(10):=1;
l_agg_cnt number(10):=0;
l_loc sku.location%type;
l_msg varchar2(200);

cursor c_sku_info is 
             select location, stock from sku
                order by stock desc;
Begin
for idx in c_sku_info 
loop
--dbms_output.put_line(idx.stck_cnt);
l_loc:=idx.location;
l_agg_cnt:=l_agg_cnt+idx.stock;
--dbms_output.put_line(l_agg_cnt);
if (l_agg_cnt<=110000 or l_agg_cnt >= 110000) then
update sku set grp=l_val 
where location=l_loc;
dbms_output.put_line(l_val||' '||l_agg_cnt);
--commit;
end if ;
 if l_agg_cnt >= 110000 then 
           l_val:=l_val+1;
           l_agg_cnt:=0;
          end if;
end loop;
exception
when others then
l_msg:=DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...