一个难题

ygghost 2004-07-26 03:31:38
一个表fmisbillywfl,字段有iid(主键),caption,code.
=============
现金流量分类\经营活动\支付的其他与经营活动有关的现金\下拨经费 01010704
现金流量分类\经营活动\支付的其他与经营活动有关的现金\其他经营流出 01010705
现金流量分类\投资活动\收回投资所收到的现金 010201
=============
其中caption用“\”分割和code字段的2位一分割是对应的。

我现在希望把这样的数据转换到如下结构(树型结构)中。
pid是父结点的id值。childcount表示是否是字结点。code与上表中code分割对应。
==============
id Title pid childcount CODE
1 现金流量分类 0 1 01
2 经营活动 1 1 01
3 投资活动 1 1 02
4 支付的其他与经营活动有关的现金 2 1 07
5 下拨经费 4 0 04
6 其他经营流出 4 0 05
7 收回投资所收到的现金 3 0 01
==============

这样的功能如何实现?请大家帮忙!
...全文
152 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
ygghost 2004-07-26
  • 打赏
  • 举报
回复
thank you
zjcxc 2004-07-26
  • 打赏
  • 举报
回复
现在可以了,上面这个示例改进了处理,原来的处理要求Title不重复
现在这个处理Title重复也可以处理

对于 childcount ,给出了两种统计方式
一种是只统计直接的子结点(测试给出的结果)
另一种是统计所有的下级
zjcxc 2004-07-26
  • 打赏
  • 举报
回复
--测试

--测试数据
create table fmisbillywfl(
iid int identity(1,1) primary key,
caption varchar(100),
code varchar(10))
insert fmisbillywfl select '现金流量分类\经营活动\支付的其他与经营活动有关的现金\下拨经费' ,'01010704'
union all select '现金流量分类\经营活动\支付的其他与经营活动有关的现金\其他经营流出','01010705'
union all select '现金流量分类\投资活动\收回投资所收到的现金' ,'010201'
go

--创建一个自定义函数,实现分解
create function f_split(
@s varchar(8000),
@pos int
)returns varchar(8000)
as
begin
declare @i int

set @i=charindex('\',@s)
while @i>0 and @pos>1
select @s=substring(@s,@i+1,8000)
,@i=charindex('\',@s)
,@pos=@pos-1
return(case @pos when 1
then case when @i>0 then left(@s,@i-1) else @s end
else '' end)
end
go

--分拆结果表
create table tb(id int,Title varchar(30),pid int,childcount int,CODE char(2))

--分拆处理
declare @i int
select @i=max(len(code))/2+1 from fmisbillywfl
set rowcount @i
select id=identity(int,0,1),a=0 into #tt from sysobjects,syscolumns
set @i=@i-@@rowcount
while @i>0
begin
insert #tt select 0 from sysobjects,syscolumns
set @i=@i-@@rowcount
end
set rowcount 0

select distinct CODE=substring(a.code,b.id*2+1,2),
Title=dbo.f_split(a.caption,b.id+1),
c_id=left(a.code,b.id*2+2),c_pid=left(a.code,b.id*2),
level=0,id=0,pid=0,childcount=0
into #t
from fmisbillywfl a,#tt b where b.id<len(a.code)/2

declare @l int,@id int
select @l=1,@id=0
update #t set @id=@id+1,id=@id,level=@l
where c_pid=''
while @@rowcount>0
begin
set @l=@l+1
update a set @id=@id+1,id=@id,
pid=b.id,level=@l
from #t a,#t b
where a.id=0 and b.level=@l-1
and a.c_pid=b.c_id
end

insert tb
select id,title,pid,
(select count(*) from #t where level=a.level+1 and c_id like a.c_id+'%'), --如果只包含下级
-- (select count(*) from #t where level>a.level and c_id like a.c_id+'%'), --如果包含所有下级
code
from #t a order by id
drop table #t,#tt
go

--显示处理结果
select * from tb
go

--删除测试
drop table fmisbillywfl,tb
drop function f_split

/*--测试结果


id Title pid childcount CODE
----------- ------------------------------ ----------- ----------- ----
1 现金流量分类 0 2 01
2 经营活动 1 1 01
3 投资活动 1 1 02
4 收回投资所收到的现金 3 0 01
5 支付的其他与经营活动有关的现金 2 2 07
6 下拨经费 5 0 04
7 其他经营流出 5 0 05

(所影响的行数为 7 行)
--*/
ygghost 2004-07-26
  • 打赏
  • 举报
回复
zjcxc(邹建):现在就childcount这个字段有问题,导致有的本来没有子结点的,现在都可以点开来,但是为空。

那个字段很很多情况!
================
现金流量分类\筹资活动\支付其他与筹资活动有关的现金\下拨折旧款
现金流量分类\经营活动\收到的税费返还
现金流量分类\转户或提现

====================

下拨折旧款,收到的税费返还,转户或提现

这3个都应该是0的!
zjcxc 2004-07-26
  • 打赏
  • 举报
回复
我统计想错了,直接下级应该直接用语句统计.
ygghost 2004-07-26
  • 打赏
  • 举报
回复
zjcxc(邹建) :
十分感谢!就是你说的第2种情况。
还有个小问题,
*******有的title的childcount应该是0的,但是结果不是0******

比如你的测试结果!
id Title pid childcount CODE
4 收回投资所收到的现金 3 2 01

这个的childcount应该是0。

我想你是不是没有区分2级,3级,4级科目?你可能全是按照4级来处理的吧?
pengda1i 2004-07-26
  • 打赏
  • 举报
回复
直接下级应该是:
id Title pid childcount CODE
----------- ------------------------------ ----------- ----------- ----
1 现金流量分类 0 2 01
2 经营活动 1 1 01
3 投资活动 1 1 02
4 收回投资所收到的现金 3 0 01
5 支付的其他与经营活动有关的现金 2 1 07
6 下拨经费 5 0 04
7 其他经营流出 5 0 05

(所影响的行数为 7 行)
zjcxc 2004-07-26
  • 打赏
  • 举报
回复
childcount如果是指每级的直接下级的话,就用上面的
zjcxc 2004-07-26
  • 打赏
  • 举报
回复
--测试

--测试数据
create table fmisbillywfl(
iid int identity(1,1) primary key,
caption varchar(100),
code varchar(10))
insert fmisbillywfl select '现金流量分类\经营活动\支付的其他与经营活动有关的现金\下拨经费' ,'01010704'
union all select '现金流量分类\经营活动\支付的其他与经营活动有关的现金\其他经营流出','01010705'
union all select '现金流量分类\投资活动\收回投资所收到的现金' ,'010201'
go

--创建一个自定义函数,实现分解
create function f_split(
@s varchar(8000),
@pos int
)returns varchar(8000)
as
begin
declare @i int

set @i=charindex('\',@s)
while @i>0 and @pos>1
select @s=substring(@s,@i+1,8000)
,@i=charindex('\',@s)
,@pos=@pos-1
return(case @pos when 1
then case when @i>0 then left(@s,@i-1) else @s end
else '' end)
end
go

--分拆结果表
create table tb(id int,Title varchar(30),pid int,childcount int,CODE char(2))

--分拆处理
declare @i int
select @i=max(len(code))/2+1 from fmisbillywfl
set rowcount @i
select id=identity(int,0,1),a=0 into #tt from sysobjects,syscolumns
set @i=@i-@@rowcount
while @i>0
begin
insert #tt select 0 from sysobjects,syscolumns
set @i=@i-@@rowcount
end
set rowcount 0

select distinct CODE=substring(a.code,b.id*2+1,2),
Title=dbo.f_split(a.caption,b.id+1),
pTitle=dbo.f_split(a.caption,b.id),
level=0,id=0,pid=0,childcount=0
into #t
from fmisbillywfl a,#tt b where b.id<len(a.code)/2

declare @l int,@id int
select @l=1,@id=0
update #t set @id=@id+1,id=@id,level=@l
where pTitle=''
while @@rowcount>0
begin
set @l=@l+1
update a set @id=@id+1,id=@id,
pid=b.id,level=@l
from #t a,#t b
where a.id=0 and b.level=@l-1
and a.pTitle=b.Title
update #t set childcount=@@rowcount where level=@l-1
end

insert tb
select id,title,pid,childcount,code from #t order by id
drop table #t,#tt
go

--显示处理结果
select * from tb
go

--删除测试
drop table fmisbillywfl,tb
drop function f_split

/*--测试结果


id Title pid childcount CODE
----------- ------------------------------ ----------- ----------- ----
1 现金流量分类 0 2 01
2 经营活动 1 2 01
3 投资活动 1 2 02
4 收回投资所收到的现金 3 2 01
5 支付的其他与经营活动有关的现金 2 2 07
6 下拨经费 5 0 04
7 其他经营流出 5 0 05

(所影响的行数为 7 行)

--*/
zjcxc 2004-07-26
  • 打赏
  • 举报
回复
id的顺序有所变化,但上下级的属性没有错.
zjcxc 2004-07-26
  • 打赏
  • 举报
回复
--测试

--测试数据
create table fmisbillywfl(
iid int identity(1,1) primary key,
caption varchar(100),
code varchar(10))
insert fmisbillywfl select '现金流量分类\经营活动\支付的其他与经营活动有关的现金\下拨经费' ,'01010704'
union all select '现金流量分类\经营活动\支付的其他与经营活动有关的现金\其他经营流出','01010705'
union all select '现金流量分类\投资活动\收回投资所收到的现金' ,'010201'
go

--创建一个自定义函数,实现分解
create function f_split(
@s varchar(8000),
@pos int
)returns varchar(8000)
as
begin
declare @i int

set @i=charindex('\',@s)
while @i>0 and @pos>1
select @s=substring(@s,@i+1,8000)
,@i=charindex('\',@s)
,@pos=@pos-1
return(case @pos when 1
then case when @i>0 then left(@s,@i-1) else @s end
else '' end)
end
go

--分拆结果表
create table tb(id int,Title varchar(30),pid int,childcount int,CODE char(2))

--分拆处理
declare @i int
select @i=max(len(code))/2+1 from fmisbillywfl
set rowcount @i
select id=identity(int,0,1),a=0 into #tt from sysobjects,syscolumns
set @i=@i-@@rowcount
while @i>0
begin
insert #tt select 0 from sysobjects,syscolumns
set @i=@i-@@rowcount
end
set rowcount 0

select distinct CODE=substring(a.code,b.id*2+1,2),
Title=dbo.f_split(a.caption,b.id+1),
pTitle=dbo.f_split(a.caption,b.id),
level=0,id=0,pid=0
into #t
from fmisbillywfl a,#tt b where b.id<len(a.code)/2

declare @l int,@id int
select @l=1,@id=0
update #t set @id=@id+1,id=@id,level=@l
where pTitle=''
while @@rowcount>0
begin
set @l=@l+1
update a set @id=@id+1,id=@id,
pid=b.id,level=@l
from #t a,#t b
where a.id=0 and b.level=@l-1
and a.pTitle=b.Title
end

insert tb
select id,title,pid,0,code from #t order by id
drop table #t,#tt
go

--显示处理结果
select * from tb
go

--删除测试
drop table fmisbillywfl,tb
drop function f_split

/*--测试结果

id Title pid childcount CODE
----------- ------------------------------ ----------- ----------- ----
1 现金流量分类 0 0 01
2 经营活动 1 0 01
3 投资活动 1 0 02
4 收回投资所收到的现金 3 0 01
5 支付的其他与经营活动有关的现金 2 0 07
6 下拨经费 5 0 04
7 其他经营流出 5 0 05

(所影响的行数为 7 行)
--*/
zjcxc 2004-07-26
  • 打赏
  • 举报
回复

--创建一个自定义函数,实现分解
create function f_split(
@s varchar(8000),
@pos int
)returns varchar(8000)
as
begin
declare @i int

set @i=charindex('\',@s)
while @i>0 and @pos>1
select @s=substring(@s,@i+1,8000)
,@i=charindex('\',@s)
,@pos=@pos-1
return(case @pos when 1
then case when @i>0 then left(@s,@i-1) else @s end
else '' end)
end
go

--分拆结果表
create table tb(id int,Title varchar(30),pid int,childcount int,CODE char(2))

--分拆处理
declare @i int
select @i=max(len(code))/2+1 from fmisbillywfl
set rowcount @i
select id=identity(int,0,1),a=0 into #tt from sysobjects,syscolumns
set @i=@i-@@rowcount
while @i>0
begin
insert #tt select 0 from sysobjects,syscolumns
set @i=@i-@@rowcount
end
set rowcount 0

select distinct CODE=substring(a.code,b.id*2+1,2),
Title=dbo.f_split(a.caption,b.id+1),
pTitle=dbo.f_split(a.caption,b.id),
level=0,id=0,pid=0
into #t
from fmisbillywfl a,#tt b where b.id<len(a.code)/2

declare @l int,@id int
select @l=1,@id=0
update #t set @id=@id+1,id=@id,level=@l
where pTitle=''
while @@rowcount>0
begin
set @l=@l+1
update a set @id=@id+1,id=@id,
pid=b.id,level=@l
from #t a,#t b
where a.id=0 and b.level=@l-1
and a.pTitle=b.Title
end

insert tb
select id,title,pid,0,code from #t order by id
go

--显示处理结果
select * from tb
zjcxc 2004-07-26
  • 打赏
  • 举报
回复
childcount 指什么? 好像有点不对吧?
ygghost 2004-07-26
  • 打赏
  • 举报
回复
WangZWang(阿来) :不知道你哪里不明白!
pengda1i(假冒大力(V0.1)) :title不会重复,我想也是很麻烦.哎,实在不行就用别的办

法了,我想在数据库实现确实有点困难
pengda1i 2004-07-26
  • 打赏
  • 举报
回复
问题是清楚了
不过比较繁,需要想个好方法

Title不会重复吧?
WangZWang 2004-07-26
  • 打赏
  • 举报
回复
UP

中间没有表达清楚

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧