--建表语句
CREATE TABLE [dbo].[tab1](
[Id] [uniqueidentifier] PRIMARY KEY,
[Name] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[Level] [int] NULL,
[Sort] [int] NULL,
[ParentId] [uniqueidentifier] NULL
)
GO
INSERT INTO tab1 VALUES('5E70393B-F77A-4A49-8D7F-303B2DBB65DC','        生产完成',2,3,'C3581B90-ABB6-457F-A302-6AEDB193D8E2')
INSERT INTO tab1 VALUES('85632C31-7EAC-4A3B-B78B-49B03B72BA5A','    合作项目',1,1,'1C40B50A-BDC4-45FB-911D-C810AB9D6988')
INSERT INTO tab1 VALUES('919D4098-DA47-4A59-B1EF-4AB05A5FEF57','        生产中',2,1,'C3581B90-ABB6-457F-A302-6AEDB193D8E2')
INSERT INTO tab1 VALUES('053CF301-8DE1-4140-8F98-552D07EA66BC','        临时',2,0,'85632C31-7EAC-4A3B-B78B-49B03B72BA5A')
INSERT INTO tab1 VALUES('4156E175-D0A7-46A4-832C-6862188E272F','        另一个选项',2,1,'4156E175-D0A7-46A4-832C-6862188E272F')
INSERT INTO tab1 VALUES('C3581B90-ABB6-457F-A302-6AEDB193D8E2','    生产进度下拉数据',1,0,'1C40B50A-BDC4-45FB-911D-C810AB9D6988')
INSERT INTO tab1 VALUES('4076A123-260C-4D7D-8BF0-75425716E63C','        进度2',2,1,'6627F762-23E7-4B12-BFED-ADB93C201928')
INSERT INTO tab1 VALUES('6627F762-23E7-4B12-BFED-ADB93C201928','    合作伙伴进度',1,2,'1C40B50A-BDC4-45FB-911D-C810AB9D6988')
INSERT INTO tab1 VALUES('1C40B50A-BDC4-45FB-911D-C810AB9D6988','基础数据',0,0,'00000000-0000-0000-0000-000000000000')
INSERT INTO tab1 VALUES('99D99D48-6F6D-414C-B9BF-EB75F4F3CC77','        外包中',2,2,'C3581B90-ABB6-457F-A302-6AEDB193D8E2')
INSERT INTO tab1 VALUES('C8D85D6C-80EC-4BD5-84DA-FE3C7B02DAF3','        进度1',2,0,'6627F762-23E7-4B12-BFED-ADB93C201928')
GO
SELECT * FROM tab1 ORDER BY sort,[level]
--想得到的结果和这个类似。但这个不对

解决方案 »

  1.   

    是不是BOM?
    就是按父节点展开
      

  2.   

    create table test(id int,pid int,name varchar(10))
    insert into test 
    select 1,0,'学习总结' union 
    select 2,4,'鼠标事件' union
    select 3,4,'tree'     union 
    select 4,6,'swing'    union 
    select 6,1,'java'    union 
    select 7,1,'C++'     union 
    select 9,6,'eclipse' 
    gocreate function f_getNum(@id int)
    returns varchar(4000)
    as
    begin
        declare @ret varchar(4000),@pid int
        set @ret = right('0000'+rtrim(@id),4)
        while exists(select 1 from test where id=@id and pid!=0)
        begin
            select @pid=pid from test where id=@id and pid!=0
            set @id = @pid
            set @ret = right('0000'+rtrim(@id),4)+@ret
        end
        return @ret
    end
    goselect REPLICATE('-',len(dbo.f_getNum(id))/4-1)+name as name  from test order by dbo.f_getNum(id)
    /*
    name       
    ---------- 
    学习总结
    -java
    --swing
    ---鼠标事件
    ---tree
    --eclipse
    -C++
    */
    godrop function f_getNum
    drop table test
    go
      

  3.   

    SELECT * FROM tab1 ORDER BY sort,[level]
    的查询结果是不对的
    注意看
    进度1和进度2都是属于合作伙伴进度的
    基础数据
        生产进度下拉数据
            生产中
            外包中
            生产完成
        合作项目
            临时
        合作伙伴进度
            进度1
           进度2
      

  4.   

    深度排序
    --测试数据   深度排序     
      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   @t_Level   TABLE(ID   char(3),Level   int,Sort   varchar(8000))   
      DECLARE   @Level   int   
      SET   @Level=0   
      INSERT   @t_Level   SELECT   ID,@Level,ID   
      FROM   @t   
      WHERE   PID   IS   NULL   
      WHILE   @@ROWCOUNT>0   
      BEGIN   
      SET   @Level=@Level+1   
      INSERT   @t_Level   SELECT   a.ID,@Level,b.Sort+a.ID   
      FROM   @t   a,@t_Level   b   
      WHERE   a.PID=b.ID   
      AND   b.Level=@Level-1   
      END   
        
      --显示结果   
      SELECT   a.*   
      FROM   @t   a,@t_Level   b   
      WHERE   a.ID=b.ID   
      ORDER   BY   b.Sort   
      /*--结果   
      ID       PID       Name                 
      ------   ---------   ----------     
      001     NULL   山东省   
      002     001       烟台市   
      004     002       招远市   
      003     001       青岛市   
      005     NULL   四会市   
      006     005       清远市   
      007     006       小分市   
      --*/--查询指定节点及其所有子节点的函数   
      CREATE   FUNCTION   f_Cid(@ID   char(3))   
      RETURNS   @t_Level   TABLE(ID   char(3),Level   int)   
      AS   
      BEGIN   
      DECLARE   @Level   int   
      SET   @Level=1   
      INSERT   @t_Level   SELECT   @ID,@Level   
      WHILE   @@ROWCOUNT>0   
      BEGIN   
      SET   @Level=@Level+1   
      INSERT   @t_Level   SELECT   a.ID,@Level   
      FROM   tb   a,@t_Level   b   
      WHERE   a.PID=b.ID   
      AND   b.Level=@Level-1   
      END   
      RETURN   
      END   
      GO   
        
      --调用函数查询002及其所有子节点   
      SELECT   a.*   
      FROM   tb   a,f_Cid('002')   b   
      WHERE   a.ID=b.ID   
      /*--结果   
      ID       PID     Name                 
      ------   -------   ----------     
      002     001     烟台市   
      004     002     招远市   
      --*/ --测试数据
    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 @t_Level TABLE(ID char(3),Level int,Sort varchar(8000))
    DECLARE @Level int
    SET @Level=0
    INSERT @t_Level SELECT ID,@Level,ID
    FROM @t
    WHERE PID IS NULL
    WHILE @@ROWCOUNT>0
    BEGIN
        SET @Level=@Level+1
        INSERT @t_Level SELECT a.ID,@Level,b.Sort+a.ID
        FROM @t a,@t_Level b
        WHERE a.PID=b.ID
            AND b.Level=@Level-1
    END--显示结果
    SELECT SPACE(b.Level*2)+'|--'+a.Name
    FROM @t a,@t_Level b
    WHERE a.ID=b.ID
    ORDER BY b.Sort
    /*--结果
    |--山东省
      |--烟台市
        |--招远市
      |--青岛市
    |--四会市
      |--清远市
        |--小分市
    --*/
      

  5.   

    参考:[code=SQL]
    /*
    标题:查询所有顶级节点及其子节点的例
    地址:http://topic.csdn.net/u/20090323/21/63a91f51-c4df-464d-ba18-64343deb4e3a.html
    作者:爱新觉罗·毓华(十八年风雨,守得冰山雪莲花开)
    时间:2009-03-23
    地点:广东深圳
    */[code=SQL]create table Area (id int identity,Name varchar(10) ,order_by int ,father_ID int )
    insert into area values('广东省',2,0) 
    insert into area values('四川省',2,0) 
    insert into area values('湖北省',2,0) 
    insert into area values('东莞市',1,1) 
    insert into area values('广州市',1,1) 
    insert into area values('天河区',0,5) 
    insert into area values('绵阳市',1,2) 
    insert into area values('武汉市',1,3) 
    insert into area values('汉口区',0,8) 
    insert into area values('随州市',1,3)
    goselect * from areadrop table area/*
    id          Name       order_by    father_ID   
    ----------- ---------- ----------- ----------- 
    1           广东省        2           0
    2           四川省        2           0
    3           湖北省        2           0
    4           东莞市        1           1
    5           广州市        1           1
    6           天河区        0           5
    7           绵阳市        1           2
    8           武汉市        1           3
    9           汉口区        0           8
    10          随州市        1           3(所影响的行数为 10 行)要求显示为:
    name           
    -------------- 
    广东省
      东莞市
      广州市
        天河区
    四川省
      绵阳市
    湖北省
      武汉市
        汉口区
      随州市(所影响的行数为 10 行)
    */
    --创建原始表
    create table Area (id int identity,Name varchar(10) ,order_by int ,father_ID int )
    insert into area values('广东省',2,0) 
    insert into area values('四川省',2,0) 
    insert into area values('湖北省',2,0) 
    insert into area values('东莞市',1,1) 
    insert into area values('广州市',1,1) 
    insert into area values('天河区',0,5) 
    insert into area values('绵阳市',1,2) 
    insert into area values('武汉市',1,3) 
    insert into area values('汉口区',0,8) 
    insert into area values('随州市',1,3)
    --创建临时表
    create table tmp (id int identity,Name varchar(10) ,order_by int ,father_ID int )
    go--创建查询指定节点及其所有子节点的函数
    create function f_cid(@ID int) returns @t_level table(id int , level int)
    as
    begin
      declare @level int
      set @level = 1
      insert into @t_level select @id , @level
      while @@ROWCOUNT > 0
      begin
        set @level = @level + 1
        insert into @t_level select a.id , @level
        from area a , @t_Level b
        where a.father_ID = b.id and b.level = @level - 1
      end
      return
    end
    go--创建存储过程并将数据插入临时表
    create proc my_proc 
    as
    begin
      declare @id as int
      set @id = 0
      while exists(select 1 from area where order_by = 2 and id > @id)
      begin
        set @id = (select min(id) from area where order_by = 2 and id > @id)
        insert into tmp(Name ,order_by ,father_ID) select a.name,a.order_by ,a.father_id from area a , f_cid(@id) b where a.id = b.id order by a.id 
      end
    end
    go
    exec my_proc--从临时表提取数据并显示
    select case when order_by = 2 then name
                when order_by = 1 then '  ' + name
                when order_by = 0 then '    ' + name
           end name
    from tmp order by iddrop function f_cid
    drop proc my_proc
    drop table area , tmp/*
    name           
    -------------- 
    广东省
      东莞市
      广州市
        天河区
    四川省
      绵阳市
    湖北省
      武汉市
        汉口区
      随州市(所影响的行数为 10 行)*/[/code]