【情况描述】
有表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