题目如下:
    
    我国的行政区划分为省,市,县,乡,村,现要求在数据库中用一张表存储我国的所有行政单位(如浙江省,杭州市等)及其等级关系(如浙江省包括杭州市),请写出表结构并放置一些数据作为例子,并写出求浙江省所有乡的名称的SQL语句。    请各位高手不惜赐教,谢谢!

解决方案 »

  1.   

    [code=SQL]--测试数据   深度排序     
      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
    /*--结果
    |--山东省
      |--烟台市
        |--招远市
      |--青岛市
    |--四会市
      |--清远市
        |--小分市
    --*/
      

  2.   

    /*--树形数据处理方案   
        
      树形数据的排序,新增,修改,复制,删除,数据完整性检查,汇总统计   
      --邹建   2003.9--*/   
        
      /*--数据测试环境   
      表名tb,如果修改表名,则相应修改所有数据处理中涉及到的表名tb   
      id为编号(标识字段+主键)   
      pid为上级编号   
      name为名称,后面可以自行增加其他字段.   
        
      凡是未特殊标注的地方,对自行增加的字段不影响处理结果   
      --*/   
        
      create   table   tb(id   int   identity(1,1)   not   null   constraint   PK_tb   primary   key   clustered   
      ,pid   int,name   varchar(20))   
      insert   into   tb   
      select   0,'中国'   
      union   all   select   0,'美国'   
      union   all   select   0,'加拿大'   
      union   all   select   1,'北京'   
      union   all   select   1,'上海'   
      union   all   select   1,'江苏'   
      union   all   select   6,'苏州'   
      union   all   select   7,'常熟'   
      union   all   select   6,'南京'   
      union   all   select   6,'无锡'   
      union   all   select   2,'纽约'   
      union   all   select   2,'旧金山'   
      go   
    /*--数据处理--*/   
        
      /*--   一个重要的函数,很多处理的地方都会用到   --*/   
      --自定义函数--获取编码累计   
      create   function   f_getmergid(@id   int)   
      returns   varchar(8000)   
      as   
      begin   
      declare   @re   varchar(8000),@pid   int   
        
      --为了数字排序正常,需要统一编码宽度   
      declare   @idlen   int,@idheader   varchar(20)   
      select   @idlen=max(len(id))   
      ,@idheader=space(@idlen)   
      from   tb   
        
      --得到编码累计   
      set   @re=right(@idheader+cast(@id   as   varchar),@idlen)   
      select   @pid=pid   from   tb   where   id=@id   
      while   @@rowcount>0   
      select   @re=right(@idheader+cast(@pid   as   varchar),@idlen)+','+@re   
      ,@pid=pid   from   tb   where   id=@pid   
      return(@re)   
      end   
      go   
    /*--数据显示排序--*/   
      --分级显示--横向,先一级,后二级...   
      select   *   from   tb   order   by   pid   
        
      --分级显示--纵向   
      select   *   from   tb   order   by   dbo.f_getmergid(id)   
      go   
        
      /*--数据统计--*/   
      --分级统计,每个地区下的明细地区数   
      select   *,   
      明细地区数=(select   count(*)   from   tb   where   dbo.f_getmergid(id)   like   dbo.f_getmergid(a.id)+',%')   
      from   tb   a   order   by   dbo.f_getmergid(id)   
        
      go   
      /*--数据新增,修改   
        
      数据新增,修改(包括修改所属的类别)没有什么技巧   
      ,只需要检查所属的上级是否存在就行了.这个可以简单的用下面的语句来解决:   
      if   exists(select   1   from   tb   where   id=@id)   print   '存在'   else   print   '不存在'   
      --*/   
        
      /*--数据删除--*/   
      create   proc   p_delete   
      @id   int, --要删除的id   
      @deletechild   bit=0 --是否删除子   1.删除子,0.如果@id有子,则删除失败.   
      as   
      if   @deletechild=1   
      delete   from   tb   where   dbo.f_getmergid(id)   like   dbo.f_getmergid(@id)+'%'   
      else   
      if   exists(select   1   from   tb   where   pid=@id)   
      goto   lbErr   
      else   
      delete   from   tb   where   id=@id   
        
      return lbErr:   
      RAISERROR   ('该结点下有子结点,不能删除',   16,   1)   
      go   
        
      --调用示例   
      --删除'美国'的数据   
      --exec   p_delete   2 --不包含子,因为有美国下有子,所以删除会出错   
      exec   p_delete   2,1 --包含子,将删除美国及所有数据   
      go    /*--数据完整性检查--*/   
      --自定义函数--检测某个编码出发,是否被循环引用   
      create   function   f_chkid(@id   int)   
      returns   bit --循环,返回1,否则返回0   
      as   
      begin   
      declare   @re   bit,@pid   int   
        
      set   @re=0   
        
      --检测   
      select   @pid=pid   from   tb   where   id=@id   
      while   @@rowcount>0   
      begin   
      if   @pid=@id   
      begin   
      set   @re=1   
      goto   lbErr   
      end   
      select   @pid=pid   from   tb   where   id=@pid   
      end   
        
      lbErr:   
      return(@re)   
      end   
      go   
        
      --显示表中的那些数据不符合规范   
      select   *   from   tb   a     
      where   not   exists(select   1   from   tb   where   id=a.pid)   
      or   dbo.f_chkid(id)=1   
      go   
        
      /*--数据复制   
        
      如果表中包含自定义字段,需要修改存储过程   
      存在嵌套不超过32层的问题.   
      --*/   
        
      --创建复制的存储过程--复制指定结点下的子结点到另一个结点下   
      create   proc   p_copy   
      @s_id   int, --复制该项下的所有子项   
      @d_id   int, --复制到此项下   
      @new_id   int --新增加项的开始编号   
      as   
      declare   @nid   int,@oid   int,@name   varchar(20)   
      select   id,name   into   #temp   from   tb   where   pid=@s_id   and   id<@new_id   
      while   exists(select   1   from   #temp)   
      begin   
      select   @oid=id,@name=name   from   #temp   
      insert   into   tb   values(@d_id,@name)   
      set   @nid=@@identity   
      exec   p_copy   @oid,@nid,@new_id   
      delete   from   #temp   where   id=@oid   
      end   
      go   
        
      --创建批量复制的存储过程--复制指定结点及其下面的所有子结点,并生成新结点   
      create   proc   p_copystr   
      @s_id   varchar(8000) --要复制项的列表,用逗号分隔   
      as   
      declare   @nid   int,@oid   int,@name   varchar(20)   
      set   @s_id=','+@s_id+','   
      select   id,name   into   #temp   from   tb   
      where   charindex(','+cast(id   as   varchar)+',',   @s_id)>0   
      while   exists(select   1   from   #temp)   
      begin   
      select   @oid=id,@name=name   from   #temp   
      insert   into   tb   values(@oid,@name)   
      set   @nid=@@identity   
      exec   p_copy   @oid,@nid,@nid   
      delete   from   #temp   where   id=@oid   
      end   
      go   
        
      --测试   
      exec   p_copystr   '5,6'   
        
      --显示处理结果   
      select   *   from   tb   order   by   dbo.f_getmergid(id)   
        
      go   
        
      --删除数据测试环境   
      drop   table   tb   
      drop   function   f_getmergid,f_chkid   
      drop   proc   p_delete,p_copystr,p_copy/*--数据完整性检查--*/   
      --自定义函数--检测某个编码出发,是否被循环引用   
      create   function   f_chkid(@id   int)   
      returns   bit --循环,返回1,否则返回0   
      as   
      begin   
      declare   @re   bit,@pid   int   
        
      set   @re=0   
        
      --检测   
      select   @pid=pid   from   tb   where   id=@id   
      while   @@rowcount>0   
      begin   
      if   @pid=@id   
      begin   
      set   @re=1   
      goto   lbErr   
      end   
      select   @pid=pid   from   tb   where   id=@pid   
      end   
        
      lbErr:   
      return(@re)   
      end   
      go   
        
      --显示表中的那些数据不符合规范   
      select   *   from   tb   a     
      where   not   exists(select   1   from   tb   where   id=a.pid)   
      or   dbo.f_chkid(id)=1   
      go   
        
      /*--数据复制   
        
      如果表中包含自定义字段,需要修改存储过程   
      存在嵌套不超过32层的问题.   
      --*/   
        
      --创建复制的存储过程--复制指定结点下的子结点到另一个结点下   
      create   proc   p_copy   
      @s_id   int, --复制该项下的所有子项   
      @d_id   int, --复制到此项下   
      @new_id   int --新增加项的开始编号   
      as   
      declare   @nid   int,@oid   int,@name   varchar(20)   
      select   id,name   into   #temp   from   tb   where   pid=@s_id   and   id<@new_id   
      while   exists(select   1   from   #temp)   
      begin   
      select   @oid=id,@name=name   from   #temp   
      insert   into   tb   values(@d_id,@name)   
      set   @nid=@@identity   
      exec   p_copy   @oid,@nid,@new_id   
      delete   from   #temp   where   id=@oid   
      end   
      go   
        
      --创建批量复制的存储过程--复制指定结点及其下面的所有子结点,并生成新结点   
      create   proc   p_copystr   
      @s_id   varchar(8000) --要复制项的列表,用逗号分隔   
      as   
      declare   @nid   int,@oid   int,@name   varchar(20)   
      set   @s_id=','+@s_id+','   
      select   id,name   into   #temp   from   tb   
      where   charindex(','+cast(id   as   varchar)+',',   @s_id)>0   
      while   exists(select   1   from   #temp)   
      begin   
      select   @oid=id,@name=name   from   #temp   
      insert   into   tb   values(@oid,@name)   
      set   @nid=@@identity   
      exec   p_copy   @oid,@nid,@nid   
      delete   from   #temp   where   id=@oid   
      end   
      go   
        
      --测试   
      exec   p_copystr   '5,6'   
        
      --显示处理结果   
      select   *   from   tb   order   by   dbo.f_getmergid(id)   
        
      go   
        
      --删除数据测试环境   
      drop   table   tb   
      drop   function   f_getmergid,f_chkid   
      drop   proc   p_delete,p_copystr,p_copy
      

  3.   

    create table Division
    (DNO int identity,
    PDNO int not null, --DNO 的父接点,如村的父亲接点为村所在的乡,乡PDNO为所在的县....
    GBCODE int Primary Key ,--国标码,如甘肃的为62
    DNAME VAECHAR(50))--名称
      

  4.   

    http://album.hi.csdn.net/views/photo/290458