I have a complex SQL query that successfully extracts the cost of component product records and calculates the overall cost of the parent/bundle product. This approach works when each component has a supplier cost and is not itself a parent/bundled product.
Query#1
SET @parentid = 36; SELECT sub.product_sku AS product_sku, sub.product_label AS product_label, c2p.bundle_parentid AS bundle_parentid, c2p.componentid AS comp_product_id, sub.qty AS qty, sub.preferred AS preferred, sub.supply_qty AS supply_qty, sub.cost AS cost, ROUND((SELECT cost)/(SELECT supply_qty),2) AS adjusted_cost FROM products AS p JOIN component2bundle AS c2p ON c2p.componentid = p.product_id JOIN ( /* Get the preferred/cheapest supplier date for this component */ SELECT p2.product_sku AS product_sku, p2.product_label AS product_label, IFNULL(s2p2.cost, NULL) AS cost, s2p2.productid AS product_id, s2p2.supplier_preferred AS preferred, s2p2.product_quantity AS supply_qty, c2p2.componentid AS comp_product_id, c2p2.component_quantity AS qty, c2p2.bundle_parentid AS bundle_parentid FROM products AS p2 INNER JOIN supplier2product AS s2p2 ON s2p2.productid = p2.product_id INNER JOIN component2bundle AS c2p2 ON s2p2.productid = c2p2.componentid WHERE c2p2.bundle_parentid = @parentid AND c2p2.c2p_archive = 0 AND COALESCE(s2p2.s2p_archive,0) = 0 ORDER BY c2p2.componentid ASC, s2p2.supplier_preferred DESC, s2p2.cost ASC ) AS sub ON (sub.product_id = c2p.componentid) WHERE c2p.bundle_parentid = @parentid;
My goal is to tweak or rewrite the query so that it eliminates the cost of any bundled components, so a recursive CTE query seems to be the way to go.
I have successfully written a CTE query that extracts each component product ID from a table showing a parent -> child relationship and assigns each component a level in the hierarchy. What I'm struggling with is how to integrate the two.
CTE Query
WITH RECURSIVE components AS ( SELECT componentid, 1 AS level FROM component2bundle WHERE bundle_parentid = 'target_productID' UNION ALL SELECT c2b.componentid, c.level+1 FROM components c, component2bundle c2b WHERE c2b.bundle_parentid = c.componentid ) SELECT * FROM components ORDER BY level DESC;
I've created a MySQL 8.0 fiddle here to help provide better context:
https://dbfiddle.uk/M6HT_R13
NOTE: I've cut down query #1 to make it easier to process so some fields in the fiddle can be ignored.
*Edit: Set the parentid variable in the fiddle to see how the current query pulls:
Some additional notes.
The subquery in query #1 is intended to extract the preferred or (if not set) lowest supplier cost from the supplier2cost table, and I'm not sure how to implement this subquery in the CTE context ( if so).
If additional context is helpful, please ask and I will edit the query to provide that information.
Expected/Expected Output
ProductSKU | product label | BundleParentID | Component_ID | level | quantity | Preferred | Supply quantity | cost | Adjusted Cost |
---|---|---|---|---|---|---|---|---|---|
Subcomponent#1 | CMP#2 | 36 | 35 | 2 | 1 | 1 | 1 | cost | Cost per unit |
Subcomponent#2 | CMP#3 | 36 | 37 | 2 | 1 | 1 | 1 | cost | Cost per unit |
Subcomponent#3 | CMP#4 | 36 | 38 | 2 | 1 | 1 | 1 | cost | Cost per unit |
Component#1 | CMP#1 | 34 | 33 | 1 | 1 | 1 | 1 | cost | Cost per unit |
Subpackage | The Bund#1 | 36 | 33 | 1 | 1 | 1 | 1 | cost | Cost per unit |
The data will ultimately be used to provide the following component cost table:
You might want something like this:
On the second
cte
, add a condition that joins your body query with the recursive query to extract only the selected queryDemo here