SQL递归,老问题了!

wangxiaofeiwuqiao 2011-08-25 05:29:41
有如下表tb1,有3个字段

SO_NUMBER CUSTOMER ITEM_CODE(实际是成品)
SO10-5257 HALLM-01 99-88551-01030
SO10-5341 HALLM-02 98-78496-SP417K
SO30-0524 HALLM-03 97-94730-02010
...

另外有表BOM1:其中PARENT与ITEM_CODE可以存在不定的多层的递归关系,层层递归,99下面是98,98下是97,97下是94,94下是91等等。比如成品99-88551-01030,它的下层96-88551-01010的下面有#8003042-01010和#6300035-01010这2个最低层的要算上去,再加上21-00001-00010,22-00424-01010一共有4个.目的就是找到所有相关最底层的物料。

PARENT(成品) ITEM_CODE(半成品或物料) BOM_UNIT
99-88551-01030 97-88551-01030 PCS
97-88551-01030 96-88551-01010 PCS
96-88551-01010 #8003042-01010 G
96-88551-01010 #6300035-01010 G
96-88551-01010 20-88551-01030 PCS
20-88551-01030 21-00001-00010 G
20-88551-01030 22-00424-01010 G

98-78496-SP417K #98-78496-SP417K G
98-78496-SP417K 97-78496-SP417K PCS
97-78496-SP417K 96-78496-SP2027 PCS
97-78496-SP417K #7678496-00010 G
97-78496-SP417K #88-78496-SP2027 G
96-78496-SP2027 94-78496-SP2027 PCS
96-78496-SP2027 #87-78496-SP2027 G
94-78496-SP2027 90-78496-01010 PCS
90-78496-01010 87-02029-00020 G
90-78496-01010 02-00002-01011 G
。。。
SO30-0524的省略

我想要的效果,查找tb1中的所有成品的成品-物料对应关系:

SO_NUMBER CUSTOMER PARENT(成品) ITEM_CODE(半成品或物料) BOM_UNIT
SO10-5257 HALLM-01 99-88551-01030 #8003042-01010 G
SO10-5257 HALLM-01 99-88551-01030 #6300035-01010 G
SO10-5257 HALLM-01 99-88551-01030 21-00001-00010 G
SO10-5257 HALLM-01 99-88551-01030 22-00424-01010 G

SO10-5341 HALLM-02 98-78496-SP417K #98-78496-SP417K G
SO10-5341 HALLM-02 98-78496-SP417K #7678496-00010 G
SO10-5341 HALLM-02 98-78496-SP417K #88-78496-SP2027 G
SO10-5341 HALLM-02 98-78496-SP417K #87-78496-SP2027 G
SO10-5341 HALLM-02 98-78496-SP417K 87-02029-00020 G
SO10-5341 HALLM-02 98-78496-SP417K 02-00002-01011 G


数据库环境SQL 2000
...全文
240 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangxiaofeiwuqiao 2011-08-26
  • 打赏
  • 举报
回复
AcHerat 元老 2011-08-26
  • 打赏
  • 举报
回复
2000用函数是有点慢,也没别的办法,看看能不能优化下吧!遇到递归就很折腾人了。
wangxiaofeiwuqiao 2011-08-26
  • 打赏
  • 举报
回复
小三,我试了下,我放到项目上,BOM1里面有30多万数据。里面有很多的递归关系,直接在数据库查询的时候5分钟也没有出来,这种情况正常么?
wangxiaofeiwuqiao 2011-08-25
  • 打赏
  • 举报
回复
这个表是其中一步,明天还有一个问题要开贴请教小三。
wangxiaofeiwuqiao 2011-08-25
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 acherat 的回复:]
SQL code

create table tb1(SO_NUMBER varchar(50),CUSTOMER varchar(50),ITEM_CODE varchar(50))
set nocount on
insert into tb1(SO_NUMBER,CUSTOMER,ITEM_CODE)
values('SO10-5257','HALLM-01','99-88551-……
[/Quote]
小三厉害,明天一早再测试下。
xyytuo 2011-08-25
  • 打赏
  • 举报
回复
叶子 2011-08-25
  • 打赏
  • 举报
回复
sql2000只能用自定义函数,小三加油!
YiYanXiYin 2011-08-25
  • 打赏
  • 举报
回复
2000比较麻烦点,只能说方法了,自己动手去写吧: 用游标遍历tb1,在BOM1中递归出无子项的数据插入临时表

2005用with要简单些

AcHerat 元老 2011-08-25
  • 打赏
  • 举报
回复

create table tb1(SO_NUMBER varchar(50),CUSTOMER varchar(50),ITEM_CODE varchar(50))
set nocount on
insert into tb1(SO_NUMBER,CUSTOMER,ITEM_CODE)
values('SO10-5257','HALLM-01','99-88551-01030')
insert into tb1(SO_NUMBER,CUSTOMER,ITEM_CODE)
values('SO10-5341','HALLM-02','98-78496-SP417K')
insert into tb1(SO_NUMBER,CUSTOMER,ITEM_CODE)
values('SO30-0524','HALLM-03','97-94730-02010')
go

create table BOM1(PARENT varchar(50),ITEM_CODE varchar(50),BOM_UNIT varchar(50))

insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('99-88551-01030','97-88551-01030','PCS')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('97-88551-01030','96-88551-01010','PCS')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('96-88551-01010','#8003042-01010','G')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('96-88551-01010','#6300035-01010','G')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('96-88551-01010','20-88551-01030','PCS')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('20-88551-01030','21-00001-00010','G')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('20-88551-01030','22-00424-01010','G')

insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('98-78496-SP417K','#98-78496-SP417K','G')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('98-78496-SP417K','97-78496-SP417K','PCS')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('97-78496-SP417K','96-78496-SP2027','PCS')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('97-78496-SP417K','#7678496-00010','G')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('97-78496-SP417K','#88-78496-SP2027','G')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('96-78496-SP2027','94-78496-SP2027','PCS')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('96-78496-SP2027','#87-78496-SP2027','G')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('94-78496-SP2027','90-78496-01010','PCS')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('90-78496-01010','87-02029-00020','G')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('90-78496-01010','02-00002-01011','G')
set nocount off
go

create function get_proC(@PARENT varchar(50))
returns varchar(1000)
as
begin
declare @t table(PARENT varchar(50),ITEM_CODE varchar(50),[level] int)
declare @i int
declare @ret varchar(1000)
declare @j int
set @j=1
set @i=1
insert into @t
select PARENT,ITEM_CODE,@i from BOM1 where PARENT=@PARENT
while @@rowcount>0
begin
set @i=@i+1
insert into @t
select a.PARENT,a.ITEM_CODE,@i from BOM1 a join @t b on a.PARENT=b.ITEM_CODE
where b.level=@i-1
end
select @j = max([level]) from @t
select @ret = isnull(@ret+',','')+ITEM_CODE
from @t t
where not exists (select 1 from @t where PARENT = t.ITEM_CODE)
return @ret
end
go

select a.SO_NUMBER,a.CUSTOMER,a.ITEM_CODE,
b.ITEM_CODE,b.BOM_UNIT
from tb1 a join BOM1 b on charindex(','+b.ITEM_CODE+',',','+dbo.get_proC(a.ITEM_CODE)+',') > 0

--这个地方有必要就left join!

drop function get_proC
drop table tb1,BOM1

/**********************

SO_NUMBER CUSTOMER ITEM_CODE ITEM_CODE BOM_UNIT
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------------------------------------
SO10-5257 HALLM-01 99-88551-01030 #8003042-01010 G
SO10-5257 HALLM-01 99-88551-01030 #6300035-01010 G
SO10-5257 HALLM-01 99-88551-01030 21-00001-00010 G
SO10-5257 HALLM-01 99-88551-01030 22-00424-01010 G
SO10-5341 HALLM-02 98-78496-SP417K #98-78496-SP417K G
SO10-5341 HALLM-02 98-78496-SP417K #7678496-00010 G
SO10-5341 HALLM-02 98-78496-SP417K #88-78496-SP2027 G
SO10-5341 HALLM-02 98-78496-SP417K #87-78496-SP2027 G
SO10-5341 HALLM-02 98-78496-SP417K 87-02029-00020 G
SO10-5341 HALLM-02 98-78496-SP417K 02-00002-01011 G

(10 行受影响)

飘零一叶 2011-08-25
  • 打赏
  • 举报
回复
SQL 2000就算了,写着累,等小三
AcHerat 元老 2011-08-25
  • 打赏
  • 举报
回复
了解,嘿嘿……
wangxiaofeiwuqiao 2011-08-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 acherat 的回复:]
额。。。这会测试数据没问题吧!下班,回去看,肚子怎么突然不舒服了。
[/Quote]
数据没问题,千万不要不舒服哦,用藿香正气水:)。
AcHerat 元老 2011-08-25
  • 打赏
  • 举报
回复
额。。。这会测试数据没问题吧!下班,回去看,肚子怎么突然不舒服了。
wangxiaofeiwuqiao 2011-08-25
  • 打赏
  • 举报
回复
测试数据:

create table tb1(SO_NUMBER varchar(50),CUSTOMER varchar(50),ITEM_CODE varchar(50))

insert into tb1(SO_NUMBER,CUSTOMER,ITEM_CODE)
values('SO10-5257','HALLM-01','99-88551-01030')
insert into tb1(SO_NUMBER,CUSTOMER,ITEM_CODE)
values('SO10-5341','HALLM-02','98-78496-SP417K')
insert into tb1(SO_NUMBER,CUSTOMER,ITEM_CODE)
values('SO30-0524','HALLM-03','97-94730-02010')
---------------------------------------

create table BOM1(PARENT varchar(50),ITEM_CODE varchar(50),BOM_UNIT varchar(50))

insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('99-88551-01030','97-88551-01030','PCS')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('97-88551-01030','96-88551-01010','PCS')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('96-88551-01010','#8003042-01010','G')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('96-88551-01010','#6300035-01010','G')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('96-88551-01010','20-88551-01030','PCS')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('20-88551-01030','21-00001-00010','G')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('20-88551-01030','22-00424-01010','G')

insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('98-78496-SP417K','#98-78496-SP417K','G')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('98-78496-SP417K','97-78496-SP417K','PCS')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('97-78496-SP417K','96-78496-SP2027','PCS')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('97-78496-SP417K','#7678496-00010','G')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('97-78496-SP417K','#88-78496-SP2027','G')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('96-78496-SP2027','94-78496-SP2027','PCS')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('96-78496-SP2027','#87-78496-SP2027','G')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('94-78496-SP2027','90-78496-01010','PCS')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('90-78496-01010','87-02029-00020','G')
insert into BOM1(PARENT,ITEM_CODE,BOM_UNIT)
values('90-78496-01010','02-00002-01011','G')
本书是Inside Microsoft SQL Server 2005系列四本著作中的一本。它详细介绍了T-SQL的内部体系结构,包含了非常全面的编程参考,提供了使用Transact-SQL(T-SQL)的专家级指导,囊括了非常全面的编程参考,揭示了基于集合的查询的强大威力,并包含大量来自专家们的参考和建议。本书适合专业数据库开发者、BI开发者、DBA和以SQL Server作为后台数据库的一般应用程序开发者,读者可以通过书中的最佳实践、高级技巧和代码示例来掌握这门复杂的编程语言,以切合实际的方案来解决复杂的实际问题。   深入理解T-SQL体系结构,充分利用高级T-SQL查询技术。   本书深入介绍了T-SQL的内部体系结构,揭示了基于集合的查询的强大威力,并包含大量来自专家们的参考和建议。通过本书提供的最佳实践和示例代码,数据库开发人员和管理员完全可以掌握这门复杂的编程语言,以切合实际的方案来解决复杂的实际问题。通过本书,你将学习到如何:理解逻辑和物理的查询处理;使用方法论优化查询;在查询中用TOP选项修改数据;用递归逻辑、具体化路径或嵌套集合解决方案查询特殊的数据结构;通过逻辑难题提高你的逻辑能力并掌握查询问题的核心等。   你将学习到如何:   理解逻辑和物理的查询处理;   使用方法论优化查询;   解决关系分区问题;   使用CTE和排名函数简化及优化解决方案;   用各种技术聚合数据,包括附加属性、旋转、直方图和分组因子;   在查询中用TOP选项修改数据;   用递归逻辑、具体化路径或嵌套集合解决方案查询特殊的数据结构;   通过逻辑难题提高你的逻辑能力并掌握查询问题的核心; 内容简介 本书是Inside Microsoft SQL Server 2005系列四本著作中的一本。本书及其续篇——《Microsoft SQL Server 2005技术内幕:T-SQL程序设计》介绍了SQL Server 2005中高级T-SQL查询、查询优化及编程相关的知识。这两本书侧重于解决实践中的常见问题,并讨论了解决这些问题的方法。它们将向你揭示基于集合(set-based)查询的强大威力,并解释为什么它比使用游标的过程化编程(procedural programming)更具优势。同时,它还会教你识别使用基于游标解决方案与基于集合解决方案的优劣。   书中还讲述了其他几种争议较多的构造(camstruct)——如临时表、动态执行、XML和.NET集成——它们在具有强大功能的同时,也具有极大的风险。   本书适合于需要编写或检查T-SQL代码的有经验的T-SQL程序员和数据库专业人员。读者可从中学到大量精湛的技巧,这些技巧会充实您的工具箱和编码技能,并让您顺利地开发出高效的解决方案。 作者简介 Itzik Ben-Gan是Solid Quality Learning的首席导师和创始人。他从1999年开始便一直是SQL Server方面的Microsoft MVP,在世界各地讲授 T-SQL查询、编程和查询优化相关的课程,并提供相关咨询服务。他在SQL Server Magazine和MSDN上发表了多篇文章,并被邀请在许多专题会议上做过报告,包括TechEd、DevWeek、PASS和SQL Server Connections。 目录 序 前言 致谢 引言  本书的组织  系统要求  安装示例数据库  更新  代码示例  本书支持 第1章 逻辑查询处理  逻辑查询处理中的各个阶段   逻辑查询处理阶段简介  Customers/Orders场景下的示例查询  逻辑查询处理步骤详解   步骤1:执行笛卡尔乘积(交叉联接)   步聚2:应用ON筛选器(联接条件)   步骤3:添加外部行(Outer Row)   步骤4:应用WHERE筛选器   步骤5:分组   步骤6:应用CUBE或ROLLUP选项   步骤7:应用HAVING筛选器   步骤8:处理SELECT列表   步骤9:应用DISTINCT子句   步骤10:应用ORDER BY子句   步骤11:应用TOP选项  SQL Server 2005中新的逻辑处理阶段   表运算符   OVER子句   集合操作  结论 第2章 物理查询处理  查询处理期间的数据流  编译   Algebrizer   优化   使用查询计划   更新计划  结论   致谢 第3章 查询优化  本章用到的示例数据  优化方法论   分析实例级的等待   联系等待和队列   确定方案   细化到数据库/文件级别   细化到进程级别   优化索引/查询  查询优化工具   syscacheobjects   清空缓存   动态管理对象   STATISTICS IO   测量查询的运

34,596

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧