递归 MySQL 查询如何工作

问题描述 投票:0回答:1

我正在开发一个仓库管理的小型项目,我需要管理可用的物品数量。有时文章可以由一篇或多篇不同的文章组成,而这些文章又可以由其他文章组成。

示例:我有 100 升水和 100 个 1 升瓶子库存。我有“水瓶”产品,由 1 升水和 1 个一升瓶组成。

我还没有库存,但理论上我可以有100瓶水。

我已经创建了一个包含基本产品信息的 Mysql 表和一个列出了创建另一个产品所需的产品及其数量的表。

Json数据示例

{
    "products": [
        {"id": 1, "name": "Water", "quantity": 120, "compound": false, "decimal": true},
        {"id": 2, "name": "Bottles", "quantity": 240, "compound": false, "decimal": false},
        {"id": 3, "name": "Small Water Bottle", "quantity": null, "compound": true, "decimal": false},
        {"id": 4, "name": "Water Box", "quantity": null, "compound": true, "decimal": false},
        {"id": 5, "name": "Water Shelf", "quantity": null, "compound": true, "decimal": false}
    ],

    "compound_list": [
        {"id": 1, "compound_id": 3, "requirement_id": 1, "requirement_quantity": 1},
        {"id": 2, "compound_id": 3, "requirement_id": 2, "requirement_quantity": 1},
        {"id": 3, "compound_id": 4, "requirement_id": 3, "requirement_quantity": 6},
        {"id": 4, "compound_id": 5, "requirement_id": 4, "requirement_quantity": 10}
    ]
}

我的问题是创建一个递归查询来计算复合产品形成的复合产品的数量。

我想创建一个 MySQL 视图,但我不明白 CTE 递归如何与函数一起使用。

所有其他答案都没有帮助我消除疑虑。

我创建了一个有效的查询,但它仅适用于由主要产品组成的产品

SELECT 
    art.id          AS product_id,
    art.name        AS product_name,
    art.qty         AS product_requirement_qty,
    art.compound
FROM
    articles art
WHERE 
    art.compound = 0

UNION ALL

SELECT 
    art.id                      AS product_id,
    art.name                    AS product_name,
    MIN(
        CASE
            WHEN art.decimal = 1
            THEN ROUND( (art_calc.qty/lc.requirement_qty), 2)
            ELSE FLOOR( (art_calc.qty/lc.requirement_qty) ) 
        END 
    ) AS product_requirement_qty,

    art.compound
FROM
    articles art
    INNER JOIN 
        compound_list lc 
    ON lc.compound_id = art.id

    INNER JOIN
        articles art_calc 
    ON art_calc.id = lc.requirement_id

WHERE 
    art.compound = 1
GROUP BY 
    art.id;

我创建了一个递归函数(不是世界上最有效的),它是我希望在 Node.js 中接收到的内容 --> 它有效

const { performance } = require('perf_hooks');
const { exit } = require('process');

const products = [
    {"id": 1, "name": "Water",  "quantity": 100, "compound": false, "decimal": true},
    {"id": 2, "name": "Bottles", "quantity": 100, "compound": false, "decimal": false},
    {"id": 3, "name": "Small Water Bottle", "quantity": null, "compound": true, "decimal": false},
    {"id": 4, "name": "Water Box", "quantity": null, "compound": true, "decimal": false},
    {"id": 5, "name": "Water Shelf", "quantity": null, "compound": true, "decimal": false}
];

const compound_list = [
    {"id": 1, "compound_id": 3, "requirement_id": 1, "requirement_quantity": 1},
    {"id": 2, "compound_id": 3, "requirement_id": 2, "requirement_quantity": 1},
    {"id": 3, "compound_id": 4, "requirement_id": 3, "requirement_quantity": 6},
    {"id": 4, "compound_id": 5, "requirement_id": 4, "requirement_quantity": 10}
];


function ViewQty(products, compound_list){
    
    const startTime = performance.now();

    var tableQTY = [];

    products.forEach(product => {
        tableQTY.push(
            recursiveFunction(products, product, compound_list)
        );
    });

    const endTime = performance.now();

    console.table(tableQTY);

    
    const elapsedTime = endTime - startTime;
    console.log(`Execution Time: ${elapsedTime}`);
}



function recursiveFunction(products, product, compound_list){
    if(!product.compound){
        return {
            "id": product.id,
            "name": product.name,
            "quantity": product.quantity
        };
    } else {
        var components = getComponents(product.id, compound_list);
        var minQty;

        if(components.length > 0){
            var possibleQtyList = [];
            components.forEach(component => {
                var x = products.find(art => art.id === component.requirement_id);

                var obj = recursiveFunction(products, x, compound_list);

                obj.quantity /= component.requirement_quantity;

                possibleQtyList.push(obj); 
            });

            minQty = Math.min(...possibleQtyList.map(element => element.quantity));
        } else {
            minQty = 0;
        }
        
        if(product.decimal){
            minQty = minQty.toFixed(2);
        } else {
            minQty = Math.floor(minQty);
        }

        return {
            "id": product.id,
            "name": product.name,
            "quantity": minQty
        };
    }
}

function getComponents(id, compound_list){
    
    var miniList = [];

    compound_list.forEach(element => {
        if(element.compound_id === id){
            miniList.push(element);
        }
    });
    
    if(miniList.length === 0){
        return {"requirement_id": null, "requirement_quantity": 0};
    } else {
        return miniList;
    }
}

ViewQty(products, compound_list);

我希望有人可以帮助我,至少了解递归在mysql中是如何工作的

mysql tableview recursive-query
1个回答
0
投票

Per ora ho risolto il Problema realizzando una 'VIEW' dinamica realizzata nel mio caso con il backend php, realizzando una funzione ricorsiva molto simile a quella citata sopra, ma perfezionata

© www.soinside.com 2019 - 2024. All rights reserved.