PostgreSQL - Использование CURSORS для «распределения» / «разделения» количеств из 2 ТАБЛИЦ в третью ТАБЛИЦУ - PullRequest
0 голосов
/ 09 сентября 2018

У меня есть следующие 2 таблицы:

SALES_ORDERS В этой таблице содержатся заказы клиентов на покупку определенного товара

SALES ORDERS

    DROP TABLE IF EXISTS "SALES_ORDERS";

    CREATE TABLE "SALES_ORDERS" ( 
    "SO" int4,
    "ITEM" varchar(255), 
    "QTY" int4 );

    INSERT INTO "SALES_ORDERS" VALUES (101, 'iPhone RED', 39);
    INSERT INTO "SALES_ORDERS" VALUES (102, 'iPhone BLACK', 100);
    INSERT INTO "SALES_ORDERS" VALUES (103, 'iPhone RED', 34);
    INSERT INTO "SALES_ORDERS" VALUES (104, 'iPhone RED', 204);
    INSERT INTO "SALES_ORDERS" VALUES (105, 'iPhone BLACK', 50);

WORK_ORDERS Эта таблица содержит плановые заказы для выполнения заказов клиентов

WORK_ORDERS

    DROP TABLE IF EXISTS "WORK_ORDERS";

    CREATE TABLE "WORK_ORDERS" (
    "WO" int4,
    "ITEM" varchar(255),
    "QTY" int4 );

    INSERT INTO "WORK_ORDERS" VALUES (5001, 'iPhone RED', 273);
    INSERT INTO "WORK_ORDERS" VALUES (5002, 'iPhone BLACK', 50);
    INSERT INTO "WORK_ORDERS" VALUES (5003, 'iPhone RED', 28);
    INSERT INTO "WORK_ORDERS" VALUES (5004, 'iPhone BLACK', 100);

Я хочу получить вывод, указанный в третьей таблице:

SALES_ORDER_FULFILLMENT В этой таблице количество рабочих заказов распределяется по количествам заказов на продажу на основе первых полученных заказов клиентов и первых запланированных рабочих заказов

SALES_ORDER_FULFILLMENT

    DROP TABLE IF EXISTS "SALES_ORDER_FULFILLMENT";

    CREATE TABLE "SALES_ORDER_FULFILLMENT" (
      "SO" int4,
      "SO_ITEM" varchar(255),
      "SO_QTY" int4,
      "WO" int2,
      "WO_QTY" int4,
      "WO_FULFILLED_QTY" int4,
      "WO_REMAINING_QTY" int4,
      "SO_DELTA" int4
    );

    INSERT INTO "SALES_ORDER_FULFILLMENT" VALUES (101, 'iPhone RED', 39, 5001, 273, 39, 234, 0);
    INSERT INTO "SALES_ORDER_FULFILLMENT" VALUES (103, 'iPhone RED', 34, 5001, 273, 34, 200, 0);
    INSERT INTO "SALES_ORDER_FULFILLMENT" VALUES (104, 'iPhone RED', 204, 5001, 273, 200, 0, 4);
    INSERT INTO "SALES_ORDER_FULFILLMENT" VALUES (104, 'iPhone RED', 204, 5003, 28, 4, 24, 0);
    INSERT INTO "SALES_ORDER_FULFILLMENT" VALUES (102, 'iPhone BLACK', 100, 5002, 50, 50, 0, 50);
    INSERT INTO "SALES_ORDER_FULFILLMENT" VALUES (102, 'iPhone BLACK', 100, 5004, 100, 50, 50, 0);
    INSERT INTO "SALES_ORDER_FULFILLMENT" VALUES (105, 'iPhone BLACK', 50, 5004, 100, 50, 0, 0);

Я попытался использовать 2 КУРСОРА с 2 ПЕТЛЯМИ, чтобы получить рабочий_приказ, а затем все продажные-заказы для одного и того же элемента и выполнить распределение.

Однако проблема, с которой я сталкиваюсь, заключается в том, что 'work_order_qty' недостаточно для выполнить определенный 'sales_order', и CURSOR извлекает следующий 'work_order', ссылка на предыдущее невыполненное 'sales_order' теряется, поэтому назначение начинается снова.

Incorrect Allocation

Это код, который у меня есть на данный момент, имейте в виду, что это не текущий или полный код, я приведен здесь только для справки.

Я уверен, что это может быть более простой или эффективный способ сделать это. Я также искал какое-нибудь решение с рекурсивным запросом WITH, любое направление будет по-настоящему оценено, спасибо.

CREATE OR REPLACE FUNCTION "SE"."WO_ALLOCATION"()
RETURNS "pg_catalog"."void" AS $BODY$

DECLARE
so_cur cursor for SELECT * FROM "SALES_ORDERS";
so_row "SALES_ORDERS"%rowtype;
so_qty integer;
so_delta integer;

wo_cur cursor for SELECT * FROM "WORK_ORDERS";
wo_row "WORK_ORDERS"%rowtype;
wo_qty integer;
wo_fulfilled integer;
wo_remaining integer;

FOR wo_row IN wo_cur LOOP

    wo_fulfilled = 0;
    wo_remaining = wo_row."QTY";

    WHILE (wo_remaining > 0 ) LOOP

          FOR so_row IN so_cur LOOP

          so_qty = so_row."QTY";

          IF (wo_remaining > so_qty) THEN 
             wo_fulfilled = so_qty;
             wo_remaining = wo_remaining - wo_fulfilled;
             so_delta = so_qty - wo_fulfilled;
          END IF;

         IF (wo_remaining < so_qty) THEN 
             wo_fulfilled = wo_remaining;
             wo_remaining = wo_remaining - wo_fulfilled;
             so_delta = so_qty - wo_fulfilled;
         END IF;


        INSERT INTO "SALES_ORDER_FULFILLMENT" VALUES(
        so_row."SO",
        so_row."ITEM",
        so_row."QTY",
        wo_row."WO",
        wo_row."QTY",
        wo_fulfilled,
        wo_remaining,
        so_delta);

        END LOOP;

    END LOOP;

END LOOP;

  END
  $BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...