【发布时间】:2019-11-24 14:10:38
【问题描述】:
我希望创建一个能够将一系列补货完全映射到顶级需求的递归查询。
以下是有关我的问题陈述的一些详细信息:
我正在尝试设计一个递归解决方案来计算所有后续补货(及其水平)给出一个顶级需求,其中需求定义为生产或计划订单(
MIN类型)
我使用以下查询创建了这个SQLFIDDLE:
-- schema
CREATE TABLE tblInputs (
Type VARCHAR(256),
Order_No VARCHAR(256),
Planned_No VARCHAR(256),
Purchase_No VARCHAR(256),
Direction VARCHAR(256)
);
CREATE TABLE Requirements (
Order_No VARCHAR(256),
Planned_No VARCHAR(256),
Req_ID VARCHAR(256),
Req_No VARCHAR(256)
);
CREATE TABLE ReqRep (
Req_ID VARCHAR(256),
Req_No VARCHAR(256),
Rep_ID VARCHAR(256)
);
CREATE TABLE Replenishments (
Rep_ID VARCHAR(256),
Order_No VARCHAR(256),
Planned_No VARCHAR(256),
Purchase_No VARCHAR(256)
);
-- data
INSERT INTO tblInputs (Type, Order_No, Planned_No, Purchase_No, Direction)
SELECT 'Purchase', NULL, NULL, 'PO9000124798', 'PLUS' FROM DUAL
UNION ALL
SELECT 'Planned', NULL, 'PL191908851', NULL, 'PLUS' FROM DUAL
UNION ALL
SELECT 'Planned', NULL, 'PL191908852', NULL, 'PLUS' FROM DUAL
UNION ALL
SELECT 'Planned', NULL, 'PL191908853', NULL, 'PLUS' FROM DUAL
UNION ALL
SELECT 'Planned', NULL, 'PL191908854', NULL, 'PLUS' FROM DUAL
UNION ALL
SELECT 'Planned', NULL, 'PL191908855', NULL, 'PLUS' FROM DUAL
UNION ALL
SELECT 'Planned', NULL, 'PL191908853', NULL, 'PLUS' FROM DUAL
UNION ALL
SELECT 'Build', 'O103916639', NULL, NULL, 'MIN' FROM DUAL
UNION ALL
SELECT 'Production', 'O103962037', NULL, NULL, 'PLUS' FROM DUAL
UNION ALL
SELECT 'Production', 'O103933200', NULL, NULL, 'PLUS' FROM DUAL
;
INSERT INTO Requirements (Order_No, Planned_No, Req_ID, Req_No)
SELECT NULL, 'PL191908851', 'ABA', '36' FROM DUAL UNION ALL
SELECT NULL, 'PL191908852', 'CC', '93' FROM DUAL UNION ALL
SELECT NULL, 'PL191908853', 'BBA', '27' FROM DUAL UNION ALL
SELECT NULL, 'PL191908854', 'EWE', '42' FROM DUAL UNION ALL
SELECT NULL, 'PL191908855', 'WWW', '13' FROM DUAL UNION ALL
SELECT NULL, 'PL191908856', 'EEE', '33' FROM DUAL UNION ALL
SELECT NULL, 'PL191909922', 'GFW', '99' FROM DUAL UNION ALL
SELECT NULL, 'PL191910022', 'GFT', '23' FROM DUAL UNION ALL
SELECT NULL, 'PL192010120', 'THE', '54' FROM DUAL UNION ALL
SELECT 'O103962037', NULL, 'BDD', '37' FROM DUAL UNION ALL
SELECT 'O103933200', NULL, 'DFA', '63' FROM DUAL UNION ALL
SELECT 'O103547812', NULL, 'ADS', '45' FROM DUAL UNION ALL
SELECT 'O103547415', NULL, 'DWQ', '94' FROM DUAL UNION ALL
SELECT 'O103654787', NULL, 'QZX', '96' FROM DUAL UNION ALL
SELECT 'O103214217', NULL, 'NFD', '20' FROM DUAL UNION ALL
SELECT 'O103215320', NULL, 'GBV', '33' FROM DUAL UNION ALL
SELECT 'O106212219', NULL, 'ERQ', '22' FROM DUAL UNION ALL
SELECT 'O103215320', NULL, 'MRP', '11' FROM DUAL
;
INSERT INTO ReqRep (Req_ID, Req_No, Rep_ID)
SELECT 'ABA', '36', '7736' FROM DUAL UNION ALL
SELECT 'CCC', '93', '6686' FROM DUAL UNION ALL
SELECT 'BBA', '27', '5710' FROM DUAL UNION ALL
SELECT 'EWE', '42', '7634' FROM DUAL UNION ALL
SELECT 'WWW', '13', '9393' FROM DUAL UNION ALL
SELECT 'EEE', '33', '8442' FROM DUAL UNION ALL
SELECT 'GFW', '99', '5758' FROM DUAL UNION ALL
SELECT 'GFT', '23', '5988' FROM DUAL UNION ALL
SELECT 'THE', '54', '6748' FROM DUAL UNION ALL
SELECT 'BDD', '37', '7123' FROM DUAL UNION ALL
SELECT 'BDD', '37', '7124' FROM DUAL UNION ALL
SELECT 'BDD', '37', '7125' FROM DUAL UNION ALL
SELECT 'BDD', '37', '7126' FROM DUAL UNION ALL
SELECT 'DFA', '63', '7125' FROM DUAL UNION ALL
SELECT 'ADS', '45', '5855' FROM DUAL UNION ALL
SELECT 'DWQ', '80', '9419' FROM DUAL UNION ALL
SELECT 'QZX', '96', '5748' FROM DUAL UNION ALL
SELECT 'NFD', '20', '7055' FROM DUAL UNION ALL
SELECT 'ERQ', '22', '7736' FROM DUAL UNION ALL
SELECT 'MRP', '11', '7736' FROM DUAL UNION ALL
SELECT 'GBV', '33', '9999' FROM DUAL
;
INSERT INTO Replenishments(Rep_ID, Order_No, Planned_No, Purchase_No)
SELECT '7736', NULL, NULL, 'PO9000124799' FROM DUAL UNION ALL
SELECT '6686', NULL, NULL, 'PO9000124800' FROM DUAL UNION ALL
SELECT '5710', NULL, NULL, 'PO9000124801' FROM DUAL UNION ALL
SELECT '7634', NULL, NULL, 'PO9000124802' FROM DUAL UNION ALL
SELECT '9393', NULL, NULL, 'PO9000124803' FROM DUAL UNION ALL
SELECT '8442', NULL, NULL, 'PO9000124804' FROM DUAL UNION ALL
SELECT '5758', NULL, NULL, 'PO9000124805' FROM DUAL UNION ALL
SELECT '5988', NULL, NULL, 'PO9000124806' FROM DUAL UNION ALL
SELECT '6748', NULL, NULL, 'PO9000124807' FROM DUAL UNION ALL
SELECT '7123', 'O103654787', NULL, NULL FROM DUAL UNION ALL
SELECT '7124', 'O103214217', NULL, NULL FROM DUAL UNION ALL
SELECT '7125', 'O103215320', NULL, NULL FROM DUAL UNION ALL
SELECT '7126', 'O106212219', NULL, NULL FROM DUAL UNION ALL
SELECT '7125', 'O103215320', NULL, NULL FROM DUAL UNION ALL
SELECT '5855', NULL, 'PL192010120', NULL FROM DUAL UNION ALL
SELECT '9419', NULL, 'PL121122221', NULL FROM DUAL UNION ALL
SELECT '5748', NULL, 'PL272634123', NULL FROM DUAL UNION ALL
SELECT '7055', NULL, 'PL983002032', NULL FROM DUAL UNION ALL
SELECT '9999', NULL, NULL, 'PO9000124806' FROM DUAL UNION ALL
SELECT '1111', NULL, NULL, 'PO9000124806' FROM DUAL
;
对我的SQLFIDDLE 使用以下查询,我基本上可以获得第一个“级别”:
WITH
-- Use one order as an example
-- This will eventually be used for many orders at once
currOrder AS
(
SELECT
tblInputs.Order_No
FROM
tblInputs
WHERE
Direction = 'PLUS'
AND
(Type = 'Production' OR Type = 'Planned')
-- Added this for example purposes only!
AND
Order_No LIKE '%O103962037%'
),
-- Now get the details about this order being a REQUIREMENT
Req AS
(
SELECT
-- unique identifier(s), unfortunately two fields combine to make the primary key
Req_ID,
Req_No
FROM
Requirements
INNER JOIN currOrder ON currOrder.Order_No = Requirements.Order_No
),
-- This is a giant bridge table of requirements, and replenishments
-- A requirement can be made up of many replenishments, and a replenishment can satisfy many requirements
-- Find the replenishments for our specific requirement
Req_Rep AS
(
SELECT DISTINCT
ReqRep.REP_ID
FROM
ReqRep
INNER JOIN Req ON ReqRep.Req_ID = Req.Req_ID AND ReqRep.Req_No = Req.Req_No
),
-- Now, grab the replenishment data that we care about, and its details
-- Only one field will be filled in at a time depending on what the replenishment type is
Rep AS
(
SELECT DISTINCT
Req_Rep.Rep_ID,
CASE
WHEN Replenishments.Order_No IS NULL AND Replenishments.Planned_No IS NULL THEN Replenishments.Purchase_No
WHEN Replenishments.Order_No IS NULL AND Replenishments.Planned_No IS NOT NULL AND Replenishments.Purchase_No IS NULL THEN Replenishments.Planned_No
WHEN Replenishments.Order_No IS NOT NULL AND Replenishments.Planned_No IS NULL AND Replenishments.Purchase_No IS NULL THEN Replenishments.Order_No
ELSE NULL END AS The_Number
FROM
Req_Rep
INNER JOIN Replenishments on Replenishments.Rep_ID = Req_Rep.Rep_ID
)
-- Grab the results
SELECT DISTINCT * FROM Rep
使用该查询,我得到了这个数据集:
REP_ID THE_NUMBER
7123 O103654787
7125 O103215320
7124 O103214217
7126 O106212219
这向我表明,对于特定的要求(由其Order_No 指定),这些是满足它的补充。然后,对于那些补货,这是与它们相关联的元数据。
我现在需要采取The_Number 并基本上重复整个过程。并且对于作为生产订单或计划订单的每个补货,继续查找所有的补货(因为,如果补货是生产订单或计划订单,它可能会有额外的补货)
目标数据集如下所示:
| Number | Req_ID | Req_No | Rep_ID | Details | Level |
|:-----------:|:------:|:------:|:------:|:------------:|:-----:|
| O103962037 | BDD | 377 | 7123 | O103654787 | 1 |
| O103962037 | BDD | 377 | 7124 | O103214217 | 1 |
| O103962037 | BDD | 377 | 7125 | O103215320 | 1 |
| O103962037 | BDD | 377 | 7126 | O106212219 | 1 |
| O103654787 | QZX | 96 | 5748 | PL272634123 | 2 |
| O103214217 | NFD | 20 | 7055 | PL983002032 | 2 |
| O103215320 | GBV | 33 | 9999 | PO9000124806 | 2 |
| O106212219 | ERQ | 22 | 7736 | PO9000124799 | 2 |
| PL272634123 | MRP | 99 | 1111 | PO9000124806 | 3 |
| PL983002032 | EWE | 22 | 1111 | PO9000124806 | 3 |
我相信我已经在查询中实现了递归anchor,但我无法确定如何构建其余部分。任何建议表示赞赏。
我已经查看了这些帖子:
我认为我需要的行是Rep.The_Number = Requirements.Order_No,但我不知道如何定义它。
【问题讨论】:
-
是否有 7125 Rep_ID 在 Replenishments 表中有重复的原因,或者这是一个错误?
-
这是一个错误。很棒的收获。抱歉@PatrickH,我已将其删除
标签: sql oracle recursion oracle11g