SQL对BOM多级展开实现

注:本文代码源自网络,是我学习过程中看到的,写下来以后备用


代码直接粘贴就可以使用


SET NOCOUNT ON; 
USE tempdb; 
GO 
IF OBJECT_ID('dbo.Employees') IS NOT NULL 
DROP TABLE dbo.Employees; 
GO 
CREATE TABLE dbo.Employees 
( 
empid INT NOT NULL PRIMARY KEY, 
mgrid INT NULL REFERENCES dbo.Employees, 
empname VARCHAR(25) NOT NULL, 
salary MONEY NOT NULL, 
CHECK (empid <> mgrid) 
); 
INSERT INTO dbo.Employees(empid, mgrid, empname, salary) 
VALUES(1, NULL, 'David', $10000.00); 
INSERT INTO dbo.Employees(empid, mgrid, empname, salary) 
VALUES(2, 1, 'Eitan', $7000.00); 
INSERT INTO dbo.Employees(empid, mgrid, empname, salary) 
VALUES(3, 1, 'Ina', $7500.00); 
INSERT INTO dbo.Employees(empid, mgrid, empname, salary) 
VALUES(4, 2, 'Seraph', $5000.00); 
INSERT INTO dbo.Employees(empid, mgrid, empname, salary) 
VALUES(5, 2, 'Jiru', $5500.00); 
INSERT INTO dbo.Employees(empid, mgrid, empname, salary) 
VALUES(6, 2, 'Steve', $4500.00); 
INSERT INTO dbo.Employees(empid, mgrid, empname, salary) 
VALUES(7, 3, 'Aaron', $5000.00); 
INSERT INTO dbo.Employees(empid, mgrid, empname, salary) 
VALUES(8, 5, 'Lilach', $3500.00); 
INSERT INTO dbo.Employees(empid, mgrid, empname, salary) 
VALUES(9, 7, 'Rita', $3000.00); 
INSERT INTO dbo.Employees(empid, mgrid, empname, salary) 
VALUES(10, 5, 'Sean', $3000.00); 
INSERT INTO dbo.Employees(empid, mgrid, empname, salary) 
VALUES(11, 7, 'Gabriel', $3000.00); 
INSERT INTO dbo.Employees(empid, mgrid, empname, salary) 
VALUES(12, 9, 'Emilia' , $2000.00); 
INSERT INTO dbo.Employees(empid, mgrid, empname, salary) 
VALUES(13, 9, 'Michael', $2000.00); 
INSERT INTO dbo.Employees(empid, mgrid, empname, salary) 
VALUES(14, 9, 'Didi', $1500.00); 
--创建索引 
CREATE UNIQUE INDEX idx_unc_mgrid_empid ON dbo.Employees(mgrid, empid); 
go 
SELECT * FROM dbo.Employees;


---------------查找所有子节点------------
DECLARE @root AS INT; 
SET @root = 3; 
WITH SubsCTE 
AS 
( 
-- Anchor member returns root node 
SELECT empid, empname, 0 AS lvl 
FROM dbo.Employees 
WHERE empid = @root 

UNION ALL 

-- Recursive member returns next level of children 
SELECT C.empid, C.empname, P.lvl + 1 
FROM SubsCTE AS P 
JOIN dbo.Employees AS C 
ON C.mgrid = P.empid 
) 
SELECT * FROM SubsCTE; 


---------------限制递归的层数------------
--DECLARE @root AS INT; 
--SET @root = 3; 
DECLARE @maxlevels AS INT; 
SET @maxlevels = 5; 


WITH SubsCTE 
AS 
( 
SELECT empid, empname, 0 AS lvl 
FROM dbo.Employees 
--WHERE empid = @root 
UNION ALL 

SELECT C.empid, C.empname, P.lvl + 1
FROM SubsCTE AS P 
JOIN dbo.Employees AS C 
ON C.mgrid = P.empid 
AND P.lvl < @maxlevels -- 这里控制递归数 
) 
SELECT * FROM SubsCTE order by lvl;

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用递归查询(recursive query)来展开树状的BOM,例如: 假设有以下的BOM结构表: | 父级物料 | 子级物料 | 数量 | | -------- | -------- | ---- | | A | B | 2 | | A | C | 3 | | B | D | 4 | | B | E | 1 | | C | F | 2 | 使用递归查询可以展开BOM结构表: ```sql WITH RECURSIVE bom_tree(parent, child, quantity, level) AS ( SELECT parent, child, quantity, 1 FROM bom WHERE parent = 'A' UNION ALL SELECT bom.parent, bom.child, bom.quantity * bom_tree.quantity, bom_tree.level + 1 FROM bom_tree JOIN bom ON bom.parent = bom_tree.child ) SELECT parent, child, quantity, level FROM bom_tree ORDER BY level, parent, child; ``` 该查询使用了`WITH RECURSIVE`语句来定义递归查询。首先查询根节点(即`parent='A'`),并将结果保存到一个公共表达式(common table expression)中,命名为`bom_tree`。然后使用`UNION ALL`将下一级节点与公共表达式中的节点连接起来,直到所有的子节点都被查询到为止。 在每一级递归中,将当前节点的子节点与数量与父节点的数量相乘,得到当前节点的数量。同时,为了避免出现环路(circular reference),需要在递归查询中记录每个节点所在的层级(level),并在查询结果中按照层级、父节点、子节点的顺序排序。 最终的查询结果如下: | parent | child | quantity | level | | ------ | ----- | -------- | ----- | | A | B | 2 | 1 | | A | C | 3 | 1 | | B | D | 8 | 2 | | B | E | 2 | 2 | | C | F | 6 | 2 | 其中,每一行表示一个父节点和子节点的关系,以及子节点的数量。例如,第一行表示物料A包含2个物料B,第二行表示物料A包含3个物料C。第三行表示物料B包含8个物料D,第四行表示物料B包含2个物料E,第五行表示物料C包含6个物料F。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值