Merge recursive CTE results into secondary SQL Select
P粉573809727
P粉573809727 2024-01-16 18:01:02
0
1
351

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:

  • 34 => Product containing sub-bundle component (ZWK180) not found
  • 36 =​> Products with all single-level components found. *

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:

P粉573809727
P粉573809727

reply all(1)
P粉675258598

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 query

SET @parentid = 34;
WITH RECURSIVE components AS 
(
    SELECT componentid, p.product_sku, 1 AS level
    FROM component2bundle
    JOIN products p ON componentid = p.product_id
    WHERE bundle_parentid = @parentid
    UNION ALL
        SELECT c2b.componentid, product_sku, c.level+1
        FROM components c, component2bundle c2b
        WHERE c2b.bundle_parentid = c.componentid
),
CTE AS (
    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,
    c.level
    FROM products AS p
    JOIN component2bundle AS c2p ON c2p.componentid = p.product_id
    JOIN components c on c.componentid = c2p.componentid
    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.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)
)
SELECT *
FROM CTE c
WHERE preferred = 1

Demo here

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!