当前位置: 代码迷 >> Sql Server >> 考验你,这句SQL有点难!该怎么处理
  详细解决方案

考验你,这句SQL有点难!该怎么处理

热度:39   发布时间:2016-04-27 14:11:45.0
考验你,这句SQL有点难!
【情况描述】
 有表company,里面存放所有企业信息,其中有字段area_id表示该企业所属地区的id,字段company_name表示企业名称。
 有表area,里面存放所有地区信息,其中有字段id主键(对应表company中的area_id),其中p_id是该地区的上级地区id(对应自身表的id),

p_id和id是自反关系,其中字段area_name表示该地区名称。
【所需结果】
 查询时通过传入的地区id来搜索company中的所有该地区的企业,以及该地区所有下级地区的所有企业(注意:该地区的下级可能还有下级)显示

结果包括company中的所有字段和area中的所有字段(如哪位能写出该SQL只需列出每个表中的一个字段即可如:company_name和area_name)

【要求】
 通过一条SQL或视图或存储过程实现

【最终结果】
 得到本人最真诚的感谢,和所有悬赏分。

------解决方案--------------------
SQL code
--生成测试数据 create table tb(id varchar(3) , pid varchar(3) , name varchar(10))insert into tb values('001' , null  , '广东省')insert into tb values('002' , '001' , '广州市')insert into tb values('003' , '001' , '深圳市')insert into tb values('004' , '002' , '天河区')insert into tb values('005' , '003' , '罗湖区')insert into tb values('006' , '003' , '福田区')insert into tb values('007' , '003' , '宝安区')insert into tb values('008' , '007' , '西乡镇')insert into tb values('009' , '007' , '龙华镇')insert into tb values('010' , '007' , '松岗镇')go--创建用户定义函数 create function f_cid(@id varchar(10)) returns varchar(8000) as begin   declare @i int , @ret varchar(8000)   declare @t table(id varchar(10) , pid varchar(10) , level int)   set @i = 1   insert into @t select id , pid , @i from tb where id = @id   while @@rowcount <> 0   begin     set @i = @i + 1     insert into @t select a.id , a.pid , @i from tb a , @t b where a.pid = b.id and b.level = @i - 1  end   select @ret = isnull(@ret , '') + id + ',' from @t   return left(@ret , len(@ret) - 1)end go --执行查询 select id , children = isnull(dbo.f_cid(id) , '') from tb group by iddrop table tbdrop function f_cid/*id   children                               ---- ---------------------------------------001  001,002,003,004,005,006,007,008,009,010002  002,004003  003,005,006,007,008,009,010004  004005  005006  006007  007,008,009,010008  008009  009010  010*/(所影响的行数为 10 行)create table tb(id varchar(3) , pid varchar(3) , name nvarchar(10))insert into tb values('001' , null  , N'广东省')insert into tb values('002' , '001' , N'广州市')insert into tb values('003' , '001' , N'深圳市')insert into tb values('004' , '002' , N'天河区')insert into tb values('005' , '003' , N'罗湖区')insert into tb values('006' , '003' , N'福田区')insert into tb values('007' , '003' , N'宝安区')insert into tb values('008' , '007' , N'西乡镇')insert into tb values('009' , '007' , N'龙华镇')insert into tb values('010' , '007' , N'松岗镇')go;with t as(    select id , cid = id from tb     union all    select t.id , cid = tb.id     from t join tb on tb.pid = t.cid )select id , cid = STUFF((SELECT ',' + rtrim(cid) FROM t WHERE id = tb.id FOR XML PATH('')) , 1 , 1 , '')from tbgroup by idorder by id/*id   cid---- ---------------------------------------001  001,002,003,005,006,007,008,009,010,004002  002,004003  003,005,006,007,008,009,010004  004005  005006  006007  007,008,009,010008  008009  009010  010(10 行受影响)*/;with t as(    select id , name , cid = id , path = cast(name as nvarchar(100)) from tb     union all    select t.id , t.name , cid = tb.id , path = cast(tb.name as nvarchar(100))    from t join tb on tb.pid = t.cid )select id , name ,        cid = STUFF((SELECT ',' + rtrim(cid) FROM t WHERE id = tb.id FOR XML PATH('')) , 1 , 1 , ''),       path = STUFF((SELECT ',' + path FROM t WHERE id = tb.id FOR XML PATH('')) , 1 , 1 , '')from tbgroup by id , nameorder by id/*id   name       cid                                         path---- ---------- ------------------------------------------- ---------------------------------001  广东省     001,002,003,005,006,007,008,009,010,004     广东省,广州市,深圳市,罗湖区,福田区,宝安区,西乡镇,龙华镇,松岗镇,天河区002  广州市     002,004                                     广州市,天河区003  深圳市     003,005,006,007,008,009,010                 深圳市,罗湖区,福田区,宝安区,西乡镇,龙华镇,松岗镇004  天河区     004                                         天河区005  罗湖区     005                                         罗湖区006  福田区     006                                         福田区007  宝安区     007,008,009,010                             宝安区,西乡镇,龙华镇,松岗镇008  西乡镇     008                                         西乡镇009  龙华镇     009                                         龙华镇010  松岗镇     010                                         松岗镇(10 行受影响)*/drop table tb
  相关解决方案