求BOM根据阶数展开的SQL语句

本文介绍了一种在ERP系统中实现物料清单(BOM)多级展开查询的方法,使用SQL Server 2005及2000的递归查询技术,展示了如何根据父件编码和阶数展开查询子件及其用量。

我有一小型 ERP 系统,产品BOM 定义好了,可查询问题出来了
系统中没有相应的查询功能,随想 通过 查询分析器 自行写 sql 查询语句,然后导入系统中

可苦于自己sql水平有限,而这个又复杂,不能成功,
请大家不吝赐教,先行谢过

BOM表结构:(编码为虚拟出的编码,实际编码父子关系是一样的,编码定义规则与此不同)
父件编码 子件编码 用量
a a.1 2
a a.2 1
a a.3 2
a.1 a.1.1 3
a.1 a.1.2 4
a.1 a.1.3 2
a.2 a.2.1 2
a.2 a.2.2 2
a.1.1 a.1.1.1 1
a.1.1 a.1.1.2 2

要求根据录入的条件:(编码,阶数)展开:

例如录入(a,1)展开
编码 用量
a.1 2
a.2 1
a.3 2
录入(a,2)展开
编码 用量
a.1.1 2*3
a.1.2 2*4
a.1.3 2*2
a.2.1 1*2
a.2.2 1*2
a.3 2

录入(a,3)展开
编码 用量
a.1.1.1 2*3*1
a.1.1.2 2*3*2
a.1.2 2*4
a.1.3 2*2
a.2.1 1*2
a.2.2 1*2
a.3 2

-----------------------------------------------

--SQL2005

--> 生成测试数据表:bom

If not object_id('[bom]') is null
Drop table [bom]
Go
Create table [bom]([父件编码] nvarchar(5),[子件编码] nvarchar(7),[用量] int)
Insert bom
Select 'a','a.1',2 union all
Select 'a','a.2',1 union all
Select 'a','a.3',2 union all
Select 'a.1','a.1.1',3 union all
Select 'a.1','a.1.2',4 union all
Select 'a.1','a.1.3',2 union all
Select 'a.2','a.2.1',2 union all
Select 'a.2','a.2.2',2 union all
Select 'a.1.1','a.1.1.1',1 union all
Select 'a.1.1','a.1.1.2',2
Go
--Select * from bom
If not object_id('f_getbom') is null
Drop function f_getbom
Go
create function f_getbom(@No varchar(10),@lvl int)
returns table
as
return
with t as
(
select *,1 lvl from bom where 父件编码=@No
union all
select a.父件编码,a.子件编码,a.用量*b.用量,b.lvl+1 from bom a,t b where a.父件编码=b.子件编码
)
select 子件编码 as 编码,用量
from t a
where lvl<=@lvl
and not exists(
select 1
from t
where lvl<=@lvl
and a.子件编码=父件编码)
go

select * from f_getbom('a',3)
/*
编码 用量
------- -----------
a.3 2
a.2.1 2
a.2.2 2
a.1.2 8
a.1.3 4
a.1.1.1 6
a.1.1.2 12

(7 行受影响)
*/
select * from f_getbom('a',2)
/*
编码 用量
------- -----------
a.3 2
a.2.1 2
a.2.2 2
a.1.1 6
a.1.2 8
a.1.3 4

(6 行受影响)
*/
select * from f_getbom('a',1)
/*
编码 用量
------- -----------
a.1 2
a.2 1
a.3 2

(3 行受影响)
*/
-------------------------------------------------

SQL2000:

--> 生成测试数据表:bom

If not object_id('[bom]') is null
Drop table [bom]
Go
Create table [bom]([父件编码] nvarchar(5),[子件编码] nvarchar(7),[用量] int)
Insert bom
Select 'a','a.1',2 union all
Select 'a','a.2',1 union all
Select 'a','a.3',2 union all
Select 'a.1','a.1.1',3 union all
Select 'a.1','a.1.2',4 union all
Select 'a.1','a.1.3',2 union all
Select 'a.2','a.2.1',2 union all
Select 'a.2','a.2.2',2 union all
Select 'a.1.1','a.1.1.1',1 union all
Select 'a.1.1','a.1.1.2',2
Go
--Select * from bom
--
>SQL查询如下:
--
创建函数1
If not object_id('f_getbom1') is null
Drop function f_getbom1
Go
create function f_getbom1(@No varchar(10))
returns @t table(父件编码 varchar(10),子件编码 varchar(10),用量 int,lvl int)
as
begin
declare @i int
set @i=1
insert @t select *,@i from bom where 父件编码=@No
while @@rowcount>0
begin
set @i = @i + 1
insert @t
select a.父件编码,a.子件编码,a.用量*b.用量,@i
from bom a,@t b
where a.[父件编码]=b.[子件编码]
and b.lvl=@i-1
end
return
end
go
--创建函数2
If not object_id('f_getbom2') is null
Drop function f_getbom2
Go
create function f_getbom2(@No varchar(10),@lvl int)
returns table
as
return(
select 子件编码 as 编码,用量
from f_getbom1(@No) a
where lvl<=@lvl
and not exists(
select 1
from f_getbom1(@No)
where lvl<=@lvl
and a.子件编码=父件编码)
)
go
--调用查询
select * from f_getbom2('a',1)
/*
编码 用量
---------- -----------
a.1 2
a.2 1
a.3 2

(3 行受影响)
*/
select * from f_getbom2('a',2)
/*
编码 用量
---------- -----------
a.3 2
a.1.1 6
a.1.2 8
a.1.3 4
a.2.1 2
a.2.2 2

(6 行受影响)
*/
select * from f_getbom2('a',3)
/*
编码 用量
---------- -----------
a.3 2
a.1.2 8
a.1.3 4
a.2.1 2
a.2.2 2
a.1.1.1 6
a.1.1.2 12

(7 行受影响)
*/
--------------------

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值