我有一小型 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 行受影响)
*/
--------------------