Рекурсивный SQL-запрос Oracle для рабочих заданий - PullRequest
0 голосов
/ 11 мая 2018

Все,

Я пытаюсь создать рекурсивный запрос, который имеет два ввода:

  1. ITEM_ID
  2. LOT

Iесть три рабочих подзапроса:

  1. ПОЛУЧЕНИЕ
  2. BATCH
  3. INGREDIENT

Я нашел, что это возможно сделать на простом примере SQL, напримерзапроса:

WITH RECURSIVE x2 (result) AS ( 
    SELECT 1 
    UNION ALL 
    SELECT result*2 FROM x2) 
SELECT * FROM x2 LIMIT 10; 

Когда я запускаю первый подзапрос RECEIVING с 2 входами ITEM_ID + LOT , и он возвращает несколько строк, тогда его OK и SQL должны остановиться. Если нет , запрос должен начать поиск в подзапросе BATCH для Номер BATCH , этот номер пакета используется в третьем подзапросе INGREDIENT , который возвращает новый ITEM_ID + LOT для ПОЛУЧЕНИЕ .

Диаграмма для рекурсивного подзапроса

Пример:

INPUT

  1. ITEM_ID = 1765716
  2. LOT = 1EP17171590

  3. Ввести вход ITEM_ID (1765716) и LOT (1EP17171590) выполнить первый подзапрос RECEIVING => нет возвращаемых строк (если возвращает, конец SQL)

  4. Введите входные данные ITEM_ID (1765716) и LOT (1EP17171590) выполнить второй подзапрос BATCH =>возвращает BATCH_NO 351908
  5. Введите BATCH_NO (351908) выполнить третий подзапрос INGREDIENT => возвращает новые ITEM_ID (1736957) и LOT (1FP17068674) => перейти к точке 3

Пример представления

Патрик,

Я сделал этот запрос, он работает, но он слишком медленный, любая идея hблагодаря его оптимизации?

select 
  BATCH_ID,
  BATCH_NO,
  PRODUCT_ITEM_ID,
  PRODUCT_ITEM
  PRODUCT_LOT,
  INGREDIENT_ITEM_ID,
  INGREDIENT_ITEM
  INGREDIENT_LOT,
  LEVEL
FROM
  (
    SELECT 
        b.batch_id,
        b.batch_no,
        b.inventory_item_id as PRODUCT_ITEM_ID,
        b.item as PRODUCT_ITEM,
        b.lot as PRODUCT_LOT,
        i.inventory_item_id AS INGREDIENT_ITEM_ID,
        i.item as INGREDIENT_ITEM,
        i.lot as INGREDIENT_LOT
    FROM batch b
    JOIN ingredients i
    ON i.batch_id = b.batch_id
  )
CONNECT BY NOCYCLE PRIOR 
    PRODUCT_ITEM_ID = INGREDIENT_ITEM_ID
    AND PRODUCT_LOT = INGREDIENT_LOT
START WITH 
    PRODUCT_ITEM_ID = 1765716 
    AND PRODUCT_LOT = '1EP17171590'
;

1 Ответ

0 голосов
/ 11 мая 2018

Вы можете сделать это без рекурсии, как это:

Я создал таблицы для этого, используя образцы данных, которые вы предоставили на скриншоте:

create table RECIEVING
(
   ITEM_ID number,
   LOT varchar2(50)
  );

insert into RECIEVING
values(1736957,'1FP17068674');

create table BATCH
(
    BATCH number,
    ITEM_ID number,
    LOT varchar2(50)
  );

insert into BATCH
values(351908,1765716,'1EP17171590');

create table INGREDIENTS
(
  BATCH number,
  ITEM_ID number,
  LOT varchar2(50)
  );

insert into INGREDIENTS
values(351908,1736957,'1FP17068674');

Это запрос, который я использовал:

select RECIEVING.ITEM_ID,
       RECIEVING.LOT
from BATCH
join INGREDIENTS
  on BATCH.BATCH = INGREDIENTS.BATCH
join RECIEVING
  on RECIEVING.ITEM_ID = INGREDIENTS.ITEM_ID
 and RECIEVING.LOT = INGREDIENTS.LOT
where BATCH.ITEM_ID = 1765716
  and BATCH.LOT = '1EP17171590';

Если партия содержит несколько ингредиентов, она вернется более чем на 1 строку назад, если она существует в ПОЛУЧЕНИИ. Я не уверен, соответствует ли это вашим требованиям или нет.

Вывод предоставленного вами образца выглядит следующим образом:

ITEM_ID     LOT
1736957     1FP17068674

SQLFiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...