首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 递归查询的问题
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • chenghuichao
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 结帖率:
    发表于:2008-07-03 15:00:44 楼主
    id  preid
    1    0
    2    1
    3    1
    4    3
    5    3
    6    5
    7    6
    如何用sql语句将每个子级都查询出来,前提是 只给你一个 上级编号(preid)查询子级??????????
    ??????????
    20  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • happyflystone
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 4

      5

    发表于:2008-07-03 15:02:261楼 得分:0
    SQL code
    CREATE TABLE BOM(PID INT,ID INT) INSERT INTO BOM SELECT 801,101 INSERT INTO BOM SELECT 801,102 INSERT INTO BOM SELECT 801,103 INSERT INTO BOM SELECT 801,601 INSERT INTO BOM SELECT 601,101 INSERT INTO BOM SELECT 601,105 INSERT INTO BOM SELECT 601,501 INSERT INTO BOM SELECT 501,106 INSERT INTO BOM SELECT 501,121 GO CREATE FUNCTION F_GETROOT(@PID INT) RETURNS INT AS BEGIN DECLARE @ID INT WHILE EXISTS(SELECT 1 FROM BOM WHERE ID=@PID) BEGIN SET @ID=@PID SELECT @PID=PID FROM BOM WHERE ID=@ID END RETURN @PID END GO SELECT PID=DBO.F_GETROOT(PID),ID FROM BOM GO /* PID ID ----------- ----------- 801 101 801 102 801 103 801 601 801 101 801 105 801 501 801 106 801 121 */ DROP FUNCTION F_GETROOT DROP TABLE BOM GO --生成测试数据 create table BOM_1(Item int,bom_head varchar(20),bom_child varchar(20),number int,products_attribute varchar(20)) insert into BOM_1 select 1 ,'A' ,'A1',1,'采购' insert into BOM_1 select 2 ,'A' ,'A2',2,'生产' insert into BOM_1 select 3 ,'A2','A3',3,'生产' insert into BOM_1 select 4 ,'A2','A4',2,'采购' insert into BOM_1 select 5 ,'A3','A5',2,'采购' insert into BOM_1 select 6 ,'A3','A6',1,'采购' insert into BOM_1 select 7 ,'B' ,'B1',1,'采购' insert into BOM_1 select 8 ,'B' ,'B2',2,'生产' insert into BOM_1 select 9 ,'B2','B3',3,'生产' insert into BOM_1 select 10,'B2','B4',2,'采购' insert into BOM_1 select 11,'B3','B5',2,'采购' insert into BOM_1 select 12,'B3','B6',2,'采购' go --创建用户定义函数,用于取每个父节点下子节点的采购配置信息 create function f_stock(@bom_head varchar(20)) returns @t table(bom varchar(20),number int) as begin declare @level int declare @a table(bom varchar(20),number int,products_attribute varchar(20),[level] int) set @level=1 if exists(select 1 from BOM_1 where bom_head=@bom_head) insert into @a select bom_child,number,products_attribute,@level from BOM_1 where bom_head=@bom_head while exists(select 1 from @a where [level]=@level and products_attribute='生产') begin set @level=@level+1 insert into @a(bom,number,products_attribute,[level]) select a.bom_child,a.number,a.products_attribute,@level from BOM_1 a,@a b where a.bom_head=b.bom and b.[level]=@level-1 end insert into @t(bom,number) select bom,number from @a where products_attribute='采购' return end go --执行调用,取父节点'A'一个标准配置分解的采购信息及数量 select * from dbo.f_stock('A') --生成测试数据 create table BOM(ID INT,PID INT,MSG VARCHAR(1000)) insert into BOM select 1,0,NULL insert into BOM select 2,1,NULL insert into BOM select 3,1,NULL insert into BOM select 4,2,NULL insert into BOM select 5,3,NULL insert into BOM select 6,5,NULL insert into BOM select 7,6,NULL go --创建用户定义函数用于取每个父节点下子节点的采购配置信息 create function f_getChild(@ID VARCHAR(10)) returns @t table(ID VARCHAR(10),PID VARCHAR(10),Level INT) as begin declare @i int set @i = 1 insert into @t select ID,PID,@i from BOM where PID = @ID while @@rowcount<>0 begin set @i = @i + 1 insert into @t select a.ID,a.PID,@i from BOM a,@t b where a.PID=b.ID and b.Level = @i-1 end return end go --执行查询 select ID from dbo.f_getChild(3) go --输出结果 /* ID ---- 5 6 7 */ --删除测试数据 drop function f_getChild drop table BOM
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • fcuandy
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-03 15:03:432楼 得分:0
    http://topic.csdn.net/u/20080702/14/376fe99a-b6e5-4ae1-b700-83b46c33d5f5.html


    在这个proc里你加一句select * from @t 就看到结果了。

    当然,cte更方便。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • roy_88
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 2

      4

    发表于:2008-07-03 15:03:573楼 得分:0
    SQL code
    with Tree as (select * from T where preid=0 --為0 union all select a.* from T a join Tree b on b.ID=a.preid) select * from Tree
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • roy_88
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 2

      4

    发表于:2008-07-03 15:05:294楼 得分:0
    SQL code
    declare @T table([id] int,[preid] int) Insert @T select 1,0 union all select 2,1 union all select 3,1 union all select 4,3 union all select 5,3 union all select 6,5 union all select 7,6 ;with Tree as (select * from @T where preid=1 --如1時 union all select a.* from @T a join Tree b on b.ID=a.preid) select * from Tree (7 個資料列受到影響) id preid ----------- ----------- 2 1 3 1 4 3 5 3 6 5 7 6 (6 個資料列受到影響)
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ojuju10
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-03 15:23:195楼 得分:0
    SQL code
    declare @T table([id] int,[preid] int) Insert @T select 1,0 union all select 2,1 union all select 3,1 union all select 4,3 union all select 5,3 union all select 6,5 union all select 7,6; declare @i int set @i=1; with cet as ( select * from @t where id=@i union all select a.* from @t a,cet b where a.preid=b.id ) select * from cet id preid ----------- ----------- 1 0 2 1 3 1 4 3 5 3 6 5 7 6 (7 行受影响)
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hanjs
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-03 16:06:396楼 得分:0
    MSSQL为何不加个start with connect by呢?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • wzy_love_sly
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-03 16:08:177楼 得分:0
    cte很好
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • monkchen
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-03 18:08:398楼 得分:0
    楼主,这是典型的目录树问题,原来的表结构跟你的一样, 用游标和临时表能解决问题,后来用一个新方案,改变了表设计,增加一个辅助id字段,该字段是字符类型,新表的构造如下:

    create table Catalog
    (
      ID  int primary key,
      parentID int,
      AidID varchar(40) not null
    )
    AidID字段就是我说的辅助ID了,这个字段每4位(当然你可以根据需要来设定位数,4位的话能每一层表示9999个节点,即一个父节点最多有9999个直接子节点)表示一级目录,下面给数实例数据便于理解

    ID          ParentID    AidID
    3423        0            3423
    45346        3423        34235346
    4355        3423        34234355
    786          3423        34230786
    678547      786          342307868547
    454545      786          342307864545

    求某个节点的所有子孙目录就好办了
    可以这样
    declare @AidID varchar(40)
    select @AidID=AidID where ID=786
    select * from catalog where aidid like @AidID+'%'

    AidID不用手动添加, 写一个触发器for insert 生成就行了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zhiguo2008
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-04 14:44:579楼 得分:0
    JF
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zhiguo2008
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-10 11:57:3510楼 得分:0
    SQL code
    DECLARE @t TABLE(ID char(3),PID char(3),Name nvarchar(10)) INSERT @t SELECT '001',NULL ,'山东省' UNION ALL SELECT '002','001','烟台市' UNION ALL SELECT '004','002','招远市' UNION ALL SELECT '003','001','青岛市' UNION ALL SELECT '005',NULL ,'四川省' UNION ALL SELECT '006','005','清远市' UNION ALL SELECT '007','006','小分市' declare @id char(3) set @id='002' declare @t_level table(id char(3),pid char(3),level int) declare @level int set @level=1 insert @t_level select id,pid,@level from @t where pid=@id while @@rowcount>0 begin set @level=@level +1 insert into @t_level select a.[id], a.pid ,@level from @t a , @t_level b where a.pid =b.[id] and b.[level]=@level-1 end select * from @t_level
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • mcxhh2005
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-11 08:30:1011楼 得分:0
    写得都不错!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • wwd252
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-07-11 10:23:4612楼 得分:0