I am looking to create a recursive query that is able to completely map a series of replenishments, to a top level requirement.
Below is some detailed information regarding my problem statement:
I am attempting to design a recursive solution to calculate all subsequent replenishments (and their levels) give a top level requirement, where a requirement is defined as a production or planned order (a
MINtype)
I have created this SQLFIDDLE using the below query:
-- 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
;
Using the below query against my SQLFIDDLE, I can essentially get the first "level":
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
Using that query, I get this dataset:
REP_ID THE_NUMBER
7123 O103654787
7125 O103215320
7124 O103214217
7126 O106212219
Which shows me that for a specific requirement (specified by its Order_No), these are the replenishments that satisfy it. Then, for those replenishments, this is the metadata that is associated with them.
I now need to take The_Number and essentially repeat the entire process. And for each replenishment that is an production or planned order, continue to find all of the replenishments (since, if a replenishment is a production or planned order, it may have additional replenishments)
The goal dataset would look like this:
| 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 |
I believe I have already achieved the recursive anchor in my query, but I cannot determine how to build the rest. Any advice is appreciated.
I have reviewed these posts:
I think the line I need is Rep.The_Number = Requirements.Order_No, but I don't know how to define that.