注册 登录
编程论坛 SQL Server论坛

这个SQL语句怎么写?

青格儿 发布于 2008-10-10 18:03, 2376 次点击
id level rootid name
1   1      0     水果
2   2      1     瓜类 
3   3      2    西瓜
4   3      2     哈密瓜
……
显示:
id  name
3   水果/瓜类/西瓜
4   水果/瓜类/哈密瓜

也就是显示成
level 
1/2/3这样的格式 的name

这个SQL语句怎么写?请SQL高手帮我看看,怎么拼接 ?
15 回复
#2
myemail19832008-10-10 21:26
没看明白
#3
球球2008-10-11 03:29
期待!~~
写得不好,纯粹是为了练习CTE
CREATE TABLE tb
(
id int IDENTITY(1,1),
level int,
rootid int,
name nvarchar(20)
);
INSERT INTO tb VALUES(1,0,'水果')
INSERT INTO tb VALUES(2,1,'瓜类')
INSERT INTO tb VALUES(3,2,'西瓜')
INSERT INTO tb VALUES(3,2,'哈密瓜')
INSERT INTO tb VALUES(1,0,'蔬菜')
INSERT INTO tb VALUES(2,5,'小白菜')
INSERT INTO tb VALUES(3,2,'香瓜')
;
DECLARE @tn nvarchar(20),@str nvarchar(4000)
SET @str = ''
SET @tn=N'水果'
;WITH
TBS
AS
(
SELECT id,name,level FROM tb WHERE name=@tn
UNION ALL
SELECT a.id,a.name,a.level FROM tb a,TBS b
WHERE a.rootid=b.id
)
SELECT @str = @str+'/'+name FROM TBS WHERE level=1 or level=2
SET @str = right(@str , len(@str) - 1);
WITH
TBS
AS
(
SELECT id,name,level FROM tb WHERE name=@tn
UNION ALL
SELECT A.id,A.name,A.level FROM tb A,TBS B
WHERE a.rootid=b.id
)
SELECT id,(@str+'/'+name) name FROM TBS WHERE level=3
;
DROP TABLE tb

[[it] 本帖最后由 球球 于 2008-10-11 03:36 编辑 [/it]]
#4
西风独自凉2008-10-11 11:15
看不明白
#5
青格儿2008-10-11 11:47
辛苦版主了,那么晚了还在写程序。
呵呵,不过,有点问题啊

SET @tn=N'水果'
这里你定义了查询水果类,嗯,我要是想示所有的分类的呢?我用SQL2005运行了上面的,没出错,也查出了水果类,可我的表中不只水果类。

我项目用的数据库是SQL2000,我执行上面的代码,却报错:
在关键字 'WITH' 附近有语法错误。(我怎么改,它都不对?SQL2000里用不了with as ?)
with as 我查了下,它可以提高查询速度(用来做子查询用的)嗯,它都有什么用法,能简单给我讲下吗?
#6
青格儿2008-10-11 11:58
看不明白?我没表达清楚?(你们把球球版主的代码,运行一下,看看能不能明白?)

简单来说,就是从表中查询出level为3的name 列表 ,但要求显示
name时,按层级显示,显示成 层级为1/2/3的 name格式 
如: id  name
   3   水果(它的level为1)/瓜类(level 2)/西瓜(level 3)

也许是我语言表达能力不行,嗯,简单理解为,怎么从上述表(1楼)中,查询出(1楼 显示)下面的那个结果。这SQL怎么写?
#7
球球2008-10-12 10:03
所以说我在期待中啊,我这里是把条件固定死了.
这是个递归操作,为什么不另外用个字段把你要的结果保存起来,在每次插入数据时就直接查询上一父节点的PathName,然后加上自己的name,形成这个字段的值。
#8
球球2008-10-12 10:06
[bo][un]青格儿[/un] 在 2008-10-11 11:47 的发言:[/bo]

我项目用的数据库是SQL2000,我执行上面的代码,却报错:
在关键字 'WITH' 附近有语法错误。 ...


CTE是sql2005的新增功能,有递归操作的功能,可以自己调自己。在2000里运行会报错。
#9
球球2008-10-12 10:19
我在以前做的一个权限模块中就是另外用PathName保存级别Name,
比如父节点为0时的Name为‘水果’,PathName就为‘水果’,
当在‘水果’下面添加‘瓜类’时,PathName就为'瓜类'父节点的PathName+'/'+Name='水果/瓜类',
当在‘瓜类’下面添加‘西瓜’时,PathName就为'西瓜'父节点(西瓜的父节点为‘瓜类’)的PathName+'/'+Name='水果/瓜类/西瓜'.
这样避免了在显示PathName时又去递归的查询!
#10
球球2008-10-12 12:18
CREATE TABLE tb
(
id int IDENTITY(1,1),
level int,
rootid int,
name nvarchar(20)
)
GO
INSERT INTO tb VALUES(1,0,'水果')
INSERT INTO tb VALUES(2,1,'瓜类')
INSERT INTO tb VALUES(3,2,'西瓜')
INSERT INTO tb VALUES(3,2,'哈密瓜')
INSERT INTO tb VALUES(1,0,'蔬菜')
INSERT INTO tb VALUES(2,5,'青菜')
INSERT INTO tb VALUES(3,2,'香瓜')
INSERT INTO tb VALUES(3,6,'上海青')
GO
DECLARE @t TABLE
(
    id int,
    level int,
    name nvarchar(20),
    rootid int,
    path nvarchar(4000)
)
INSERT INTO @t SELECT id,level,name,rootid,name FROM tb WHERE rootid=0
WHILE @@ROWCOUNT<>0
BEGIN
    INSERT INTO @t
    SELECT b.id,b.level,b.name,b.rootid,a.path+'/'+b.name
        FROM @t a,tb b
            WHERE a.id=b.rootid AND NOT EXISTS(SELECT 1 FROM @t WHERE id=b.id)
END
SELECT id,path FROM @t WHERE level=3 OR level=4
GO
DROP TABLE tb

[[it] 本帖最后由 球球 于 2008-10-12 13:52 编辑 [/it]]
#11
provoke2008-10-12 16:07
多此一举……为什么不在应用程序中转换?千万不要说想在查询分析器中显示这样的效果哦
#12
青格儿2008-10-12 21:09
谢谢球球版主的耐心回复。
select t3.id, t1.name+'\'+t2.name+'\'+t3.name from tb t1,tb t2, tb t3 where t1.id = t2.rootid and t2.id = t3.rootid  

用存储过程也能实现吧?感兴趣的朋友们可以试写一下,当然,不感兴趣的就不用看了。很想看看存储过程是怎么实现的,这几天在学存储过程 ,还望高手指点指点
我这有个,却出错 (显示不全三级):
create procedure GetName(@IDD int,@I int output,@Result varchar(50) output)
/*@IDD叶子节点的ID,@I是返回层级数,@Result是输出字符串*/
as
  declare @ID int  
  declare @TypeName varchar(50)  
  select @ID=f.id,@TypeName=Z.name from tb f  
  inner join tb z on z.rootid=f.id
  where z.level=@IDD
  if @Typename<>''  
     begin  
        select @i=@I+1  
        exec GetName @ID,@I output,@Result output   
        select @Result=@Result+@Typename+'-'  
     end   
  return
/*Run*/
declare @I int  
declare @Result varchar(50)  
set @Result='类别-'  
set @I=1  
exec GetName 3,@I output,@Result output
#13
gxua2008-10-13 13:45
这个表有问题吧
#14
青格儿2008-10-13 22:23
这结果都查出来了,这表有什么问题?
#15
cxwl3sxl2008-10-17 22:22
[bo][un]球球[/un] 在 2008-10-12 10:06 的发言:[/bo]



CTE是sql2005的新增功能,有递归操作的功能,可以自己调自己。在2000里运行会报错。


sql2000里面应该可以通过函数来实现递归的调用吧
#16
天使与海豚2008-10-23 11:13
初学者, 有些看不明白!

有待进一步学习……
1