还是分解字段
表中数据这样:
[fID] [fName] [fFullName]
11 北京 北京
51 四川 四川
5101 成都 四川\成都
510101 锦江区 四川\成都\锦江区
51010101 南光街道 四川\成都\锦江区\南光街道
我希望一个查询出来这样的效果:
[fID] [fName] [fFullName] [省] [市] [县] [乡]
11 北京 北京 北京 NULL NULL NULL
51 四川 四川 四川 NULL NULL NULL
5101 成都 四川\成都 四川 成都 NULL NULL
510101 锦江区 四川\成都\锦江区 四川 成都 锦江区 NULL
51010101 南光街道 四川\成都\锦江区\南光街道 四川 成都 锦江区 南光街道
[解决办法]
--> 测试数据 declare @tb table ([fID] int,[fName] nvarchar(4),[fFullName] nvarchar(14),[省] nvarchar(2),[市] nvarchar(4),[县] nvarchar(4),[乡] nvarchar(4))Insert into @tb select 11,'北京','北京','','','','' union all select 51,'四川','四川','','','','' union all select 5101,'成都','四川\成都','','','','' union all select 510101,'锦江区','四川\成都\锦江区','','','','' union all select 51010101,'南光街道','四川\成都\锦江区\南光街道','','','','' Select fId,fName,fFullName, reverse(parsename(replace(reverse([fFullName]),'\','.'),1)), reverse(parsename(replace(reverse([fFullName]),'\','.'),2)), reverse(parsename(replace(reverse([fFullName]),'\','.'),3)), reverse(parsename(replace(reverse([fFullName]),'\','.'),4)) from @tb/*11 北京 北京 北京 NULL NULL NULL51 四川 四川 四川 NULL NULL NULL5101 成都 四川\成都 四川 成都 NULL NULL510101 锦江区 四川\成都\锦江区 四川 成都 锦江区 NULL51010101 南光街道 四川\成都\锦江区\南光街道 四川 成都 锦江区 南光街道*/
[解决办法]
/*fId fName fFullName [省] [市] [县] [乡]----------- ---------- ------------------------------ ---------- ---------- ---------- ----------11 北京 北京 北京 NULL NULL NULL51 四川 四川 四川 NULL NULL NULL5101 成都 四川\成都 四川 成都 NULL NULL510101 锦江区 四川\成都\锦江区 四川 成都 锦江区 NULL51010101 南光街道 四川\成都\锦江区\南光街道 四川 成都 锦江区 南光街道*/
[解决办法]
这是“层级编码树”的结构
如果可以确定各级编码的长度,就可以直接用如下的方式得到结果:
select fid ,fname ,ffullname ,[省] = (select fname from @tb a0 where a0.fid=left(a.id,2)) ,[市] = (select fname from @tb a0 where a0.fid=left(a.id,4)) ,[县] = (select fname from @tb a0 where a0.fid=left(a.id,6)) ,[乡] = (select fname from @tb a0 where a0.fid=left(a.id,8))from @tb a
[解决办法]
set nocount on declare @t1 table (fid varchar(20),fname varchar(10),ffullname varchar(100))insert into @t1 (fid,fname,ffullname) values( '11' , '北京' , '北京' )insert into @t1 (fid,fname,ffullname) values( '51' , '四川' , '四川' )insert into @t1 (fid,fname,ffullname) values( '5101' , '成都' , '四川\成都' )insert into @t1 (fid,fname,ffullname) values( '510101' , '锦江区' , '四川\成都\锦江区' )insert into @t1 (fid,fname,ffullname) values( '51010101' , '南光街道' , '四川\成都\锦江区\南光街道' )declare @t2 table (fid varchar(20),fname varchar(10),ffullname varchar(100),f1 varchar(20) null, f2 varchar(20) null,f3 varchar(20) null,f4 varchar(20) null)insert into @t2 (fid,fname,ffullname) select fid,fname,ffullname from @t1update @t2 set f1=case when charindex('\',ffullname)=0 then ffullname else left(ffullname,charindex('\',ffullname)-1) end, f2=case when charindex('\',ffullname)=0 then null else substring(ffullname,charindex('\',ffullname)+1,len(ffullname)-charindex('\',ffullname)) endupdate @t2 set f2=case when charindex('\',f2)=0 then f2 else left(f2,charindex('\',f2)-1) end, f3=case when charindex('\',f2)=0 then null else substring(f2,charindex('\',f2)+1,len(f2)-charindex('\',f2)) end where f2 is not nullupdate @t2 set f3=case when charindex('\',f3)=0 then f3 else left(f3,charindex('\',f3)-1) end, f4=case when charindex('\',f3)=0 then null else substring(f3,charindex('\',f3)+1,len(f3)-charindex('\',f3)) end where f3 is not nullselect fid,fname,ffullname,f1 [省],f2 [市],f3 [县],f4 [乡] from @t2
[解决办法]
楼上的解决方案是很好的,学习学习...
顺便插一句,巨浪,我个人觉得表t_Area采用这样的设计是糟糕的,我不了解你的业务场景,
但是我觉得你将全国所有的省、直辖市,直至乡、镇、街道、村(有些城市按区划分后,再以村划分)
都存在一张表中,连同他们直接的层次关系。这会对SQL的编写带来复杂。
个人建议:
方案一:
城市、乡、镇分别存入不同的表中;表之间建立关系(用额外字段标示层次归属);
方案二:
所有数据存入表t_Area,另建立一张表存储他们的层次关系:例如:
t_Area
FID FName
11 北京
51 四川
5101 成都
510101 锦江区
51010101 南光街道
t_Level
FID FParentID
11 NULL
51 NULL
5101 51
510101 51
510101 5101
51010101 51
51010101 5101
51010101 510101
查询时关联t_Level与t_Area表即可。
以上意见仅供参考。
[解决办法]
楼上:
其实也不尽然。这种传统的层次编码本身就体现了树的信息。楼主的表结构里,[fFullName]是多余的,问题仅此而已,
不必再另用parent-chaid关系表存储了。
[解决办法]