我正在开发一个仓库管理的小型项目,我需要管理可用的物品数量。有时文章可以由一篇或多篇不同的文章组成,而这些文章又可以由其他文章组成。
示例:我有 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中是如何工作的
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