首页 > 解决方案 > 工作订单的递归 SQL Oracle 查询

问题描述

全部,

我正在尝试创建具有两个输入的递归查询:

  1. ITEM_ID
  2. 很多

我有三个工作子查询:

  1. 接收
  2. 成分

我发现它可以在简单的 SQL 中这样做,查询示例:

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

当我使用 2 个输入ITEM_ID+LOT运行第一个子查询RECEIVING并返回一些行时,它的 OK 和 SQL 应该停止。如果不是,则查询应开始在子查询BATCH中搜索BATCH 编号,此批次编号用于第三个子查询INGREDIENT ,它为RECEIVING返回新的 ITEM_ID+LOT

递归子查询图

例子:

输入

  1. ITEM_ID=1765716
  2. 批次=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 点

示例视图

帕特里克,

我做了这个查询,它的工作,但它太慢,知道如何优化它吗?

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

标签: sqloraclesubqueryrecursive-query

解决方案


您可以在没有递归的情况下执行此操作,如下所示:

我使用您在屏幕截图中提供的示例数据创建了用于此目的的表:

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

如果一个批次有多种成分,那么只要它存在于 RECIEVING 中,它就会返回多于 1 行。我不确定这是否符合您的要求。

您提供的示例的输出如下所示:

ITEM_ID     LOT
1736957     1FP17068674

SQLFiddle


推荐阅读