这个语句怎么写??

superrg 2003-09-03 03:50:53
表结构如下:
ID(自动加1) parentID(父ID) depth(深度) name(名称) index(排序)
假设有数据如下:
1,0,1,层1,1
2,1,2,层11,1
3,1,2,层12,2
4,0,1,层2,1
5,2,2,层21,1

要求先按父ID分组,取出ID及名称,名称缩进显示,按Index升序排序
即以上数据应显示
1 -层1
2 --层11
3 --层12
4 -层2
5 --层21

这问可不可以只用一个语句写出来呢???
...全文
33 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
superrg 2003-09-04
  • 打赏
  • 举报
回复
看来是没办法了,如果没有其他更好的办法,中午就把分散了,呵
superrg 2003-09-03
  • 打赏
  • 举报
回复
to FutureSa(异想天开(Haiwer)):
仔细分析了,结果跟设想有出入的~~~
FutureSa 2003-09-03
  • 打赏
  • 举报
回复
以上是最多5层的,再多层就加多几个
left join ...
on ...

order by那里也要加

这个语句效率很低的,实际用要注意
数据很多的情况我没有测试,不知道又没有问题。

superrg 2003-09-03
  • 打赏
  • 举报
回复
to FutureSa(异想天开(Haiwer)):
多层的时候好像有问题
superrg 2003-09-03
  • 打赏
  • 举报
回复
to FutureSa(异想天开(Haiwer)):
好像在sql上可以,但在access上没有REPLICATE函数哦
FutureSa 2003-09-03
  • 打赏
  • 举报
回复
access可以把isnull函数改成iif函数
FutureSa 2003-09-03
  • 打赏
  • 举报
回复
试试:

select a.id,REPLICATE('-',a.depth)+a.name from test0112 a
left join test0112 b
on a.parentID=b.id
left join test0112 c
on b.parentID=c.id
left join test0112 d
on c.parentID=d.id
left join test0112 e
on b.parentID=e.id
order by
isnull(e.[index],isnull(d.[index],isnull(c.[index],isnull(b.[index],isnull(a.[index],0)))))

在现有数据是对的。



superrg 2003-09-03
  • 打赏
  • 举报
回复
to FutureSa(异想天开(Haiwer)):

没有办法了,因为要兼容Access和Ms Sql 97版本呀~~~
要是建这么个函数或修改表结构,倒不如增加一个排序字段来得快了
FutureSa 2003-09-03
  • 打赏
  • 举报
回复
多层不用函数和临时表不好实现,因为这里有个第归的过程
FutureSa 2003-09-03
  • 打赏
  • 举报
回复
多层(支持6层,要求每个节点的子节点不多于1000个,如果能保证每个节点的子节点更少,可以修改C1000函数以达到支持更多层):

create table test0112(
ID int,
parentID int,
depth int,
name varchar(100),
[index] int
)
go

insert test0112
select
1,0,1,'a1',1
union all
select
2,1,2,'a11',1
union all
select
3,1,2,'a12',2
union all
select
4,0,1,'b2',2
union all
select
5,4,2,'b21',1
union all
select
6,3,3,'a121',1

go

create function C1000(@depth int)
returns bigint
as
begin
declare @r bigint
declare @i int
set @i=@depth
set @r=1
while @i>0
begin
set @r=@r*1000
set @i=@i-1
end
return @r
end
go

create function GetIndex(@Id int)
returns bigint
as
begin
declare @r bigint
declare @parentID int
declare @depth int
declare @Index int
declare @Maxdepth int
declare @i int
select @Maxdepth=max(depth) from test0112
select @parentID=parentID,@depth=@Maxdepth-depth,@Index=[Index] from test0112 where id=@id
if isnull(@parentID,0)=0
set @r=dbo.C1000(@depth)*@Index
else
set @r=dbo.C1000(@depth)*@Index+dbo.GetIndex(@parentID)
return @r
end
go



调用:

select id,REPLICATE('-',depth)+name from test0112
order by dbo.GetIndex(id)

结果:
id
----------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 -a1
2 --a11
3 --a12
6 ---a121
4 -b2
5 --b21

(所影响的行数为 6 行)
superrg 2003-09-03
  • 打赏
  • 举报
回复
我想到了一个实现的思路,而且是比较简单的,不过在不用自定义函数或临时表的情况下就不知道该如何实现了,思路如下:

需要排序的计算列是这样得到的:
从第一层开始,排序的顺序为asc(序号),
以下各层是父层的排序值+asc(序号),
这样排序就绝对不会错了,思路也很清晰,不过如何实现就不好做了,前提:
不能用自定义函数,不能用临时表,不能在表中添加字段保存该值,有办法实现吗???
superrg 2003-09-03
  • 打赏
  • 举报
回复
我想到了一个实现的思路,而且是比较简单的,不过在不用自定义函数或临时表的情况下就不知道该如何实现了,思路如下:

需要排序的计算列是这样得到的:
从第一层开始,排序的顺序为asc(序号),
以下各层是父层的排序值+asc(序号),
这样排序就绝对不会错了,思路也很清晰,不过如何实现就不好做了,前提:
不能用自定义函数,不能用临时表,不能在表中添加字段保存该值,有办法实现吗???
superrg 2003-09-03
  • 打赏
  • 举报
回复
to yujohny(踏网无痕):
晕,你没有理解我的意思,假如我的name的测试数据不是这样或者为空,你的程序就报错了,再仔细看看我的问题,呵
yujohny 2003-09-03
  • 打赏
  • 举报
回复
测试结果
1 -层1
2 --层11
3 --层12
4 -层2
5 --层21
yujohny 2003-09-03
  • 打赏
  • 举报
回复
CREATE TABLE #aa(ID INT IDENTITY(1,1),
parentID INT,
depth INT,name NVARCHAR(20),[index] INT)

INSERT INTO #aa VALUES(0,1,'层1',1)
INSERT INTO #aa VALUES(1,2,'层11',1)
INSERT INTO #aa VALUES(1,2,'层12',2)
INSERT INTO #aa VALUES(0,1,'层2',1)
INSERT INTO #aa VALUES(4,2,'层21',1)

select ID,LEFT('----------------',depth)+[name] from #aa
ORDER BY LEFT(name,2),[index]

DROP TABLE #aa
superrg 2003-09-03
  • 打赏
  • 举报
回复
to txlicenhe(马可@李):
希望有高手可以通过几个自连接、外连接把它拿下来,呵呵~~~
txlicenhe 2003-09-03
  • 打赏
  • 举报
回复
一句写不出多层的吧?
superrg 2003-09-03
  • 打赏
  • 举报
回复
to pengdali(大力 V2.0):
你的缺少排序,要是我的数据是乱序输入的,你的结果就不是我期待的了~~~~
superrg 2003-09-03
  • 打赏
  • 举报
回复
to tj_dns(愉快的登山者):
是的,你看得很仔细,层2的序号应该为2,如果为1则两种结果都是正确的,即原结果以及下面的结果均正确:
4 -层2
5 --层21
1 -层1
2 --层11
3 --层12

to CrazyFor(蚂蚁):
你提供的的确是好东东,里面嵌了一个自定义函数,如果要考虑兼容Access或Sql97,这种做法可能不太可行,我希望的是直接不调用任何自定义函数,游标等直接写出来,有办法吗???
pengdali 2003-09-03
  • 打赏
  • 举报
回复
select id,REPLICATE('-',depth)+[name] from 你的表
加载更多回复(4)

34,874

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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