首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

*请教,小弟我希望得到这样的查询结果,Sql语句应该如何写?

2012-01-15 
******请问,我希望得到这样的查询结果,Sql语句应该怎么写?******数据库中是以无序的规则存储的数据MenuIDP

******请问,我希望得到这样的查询结果,Sql语句应该怎么写?******
数据库中是以无序的规则存储的数据
MenuID     ParentID     Name
10000000     F1
1010101030     F1F3F1
101010     F1F1
103010     F1F3
1020101010     F1F1F1
1020201010     F1F1F2
1020201020     F1F2F2
1010301030     F1F3F3
1010201030     F1F3F2
1020101020     F1F2F1
102010     F1F2

我希望查询出的结果是这样排序的,
即按照:父节点,子节点1,子节点1的子节点,子节点2,子节点2的子节点:
注意:数据库中的Name部分不是像下面这样,
我这里只是举个例子
MenuID     ParentID     Name
10000000     F1
101010     F1F1
1020101010     F1F1F1
1020201010     F1F1F2
102010     F1F2
1020101020     F1F2F1
1020201020     F1F2F2
103010     F1F3
1010101030     F1F3F1
1010201030     F1F3F2
1010301030     F1F3F3

[解决办法]
create table tab(MenuID varchar(10),ParentID varchar(10), Name varchar(10))
insert tab
select '10 ', '000000 ', 'F1 '
union all select '101010 ', '1030 ', 'F1F3F1 '
union all select '1010 ', '10 ', 'F1F1 '
union all select '1030 ', '10 ', 'F1F3 '
union all select '102010 ', '1010 ', 'F1F1F1 '
union all select '102020 ', '1010 ', 'F1F1F2 '
union all select '102020 ', '1020 ', 'F1F2F2 '
union all select '101030 ', '1030 ', 'F1F3F3 '
union all select '101020 ', '1030 ', 'F1F3F2 '
union all select '102010 ', '1020 ', 'F1F2F1 '
union all select '1020 ', '10 ', 'F1F2 '

select * from tab order by left(MenuID+ '0000000000 ',20)

drop table tab

/* 结果

MenuID ParentID Name
---------- ---------- ----------
10 000000 F1
1010 10 F1F1
101010 1030 F1F3F1
101020 1030 F1F3F2
101030 1030 F1F3F3
1020 10 F1F2
102010 1020 F1F2F1
102010 1010 F1F1F1
102020 1010 F1F1F2
102020 1020 F1F2F2
1030 10 F1F3

(11 row(s) affected)


*/


[解决办法]
这不就是深度排序么?
[解决办法]
--测试数据
DECLARE @t TABLE(ID int,PID int,Name nvarchar(10))
INSERT @t
select '10 ', '000000 ', 'F1 ' union all
select '101010 ', '1030 ', 'F1F3F1 ' union all
select '1010 ', '10 ', 'F1F1 ' union all
select '1030 ', '10 ', 'F1F3 ' union all
select '102010 ', '1010 ', 'F1F1F1 ' union all
select '102020 ', '1010 ', 'F1F1F2 ' union all
select '102020 ', '1020 ', 'F1F2F2 ' union all
select '101030 ', '1030 ', 'F1F3F3 ' union all
select '101020 ', '1030 ', 'F1F3F2 ' union all
select '102010 ', '1020 ', 'F1F2F1 ' union all
select '1020 ', '10 ', 'F1F2 '

--深度排序显示处理
--生成每个节点的编码累计(相同当单编号法的编码)


DECLARE @t_Level TABLE(ID int,Level int,Sort varchar(8000))
DECLARE @Level int
SET @Level=0
INSERT @t_Level SELECT ID,@Level,ID
FROM @t
WHERE PID = 0
WHILE @@ROWCOUNT> 0
BEGIN
SET @Level=@Level+1
INSERT @t_Level SELECT a.ID,@Level,b.Sort+a.ID
FROM @t a,@t_Level b
WHERE a.PID=b.ID
AND b.Level=@Level-1
END

--显示结果
SELECT a.*
FROM @t a,@t_Level b
WHERE a.ID=b.ID
ORDER BY b.Sort
/*--结果
ID PID Name
----------- ----------- ----------
10 0 F1
1010 10 F1F1
101010 1030 F1F3F1
101020 1030 F1F3F2
101030 1030 F1F3F3
1020 10 F1F2
102010 1010 F1F1F1
102010 1020 F1F2F1
102020 1010 F1F1F2
102020 1020 F1F2F2
102010 1010 F1F1F1
102010 1020 F1F2F1
102020 1010 F1F1F2
102020 1020 F1F2F2
1030 10 F1F3

(15 row(s) affected)

--*/

[解决办法]
编号长度不定的话只能用递归排序了
--测试数据
CREATE TABLE tb(ID varchar(20),PID varchar(20),Name nvarchar(10))
INSERT tb
select '10 ', '000000 ', 'F1 ' union all
select '101010 ', '1030 ', 'F1F3F1 ' union all
select '1010 ', '10 ', 'F1F1 ' union all
select '1030 ', '10 ', 'F1F3 ' union all
select '102010 ', '1010 ', 'F1F1F1 ' union all
select '102020 ', '1010 ', 'F1F1F2 ' union all
select '102020 ', '1020 ', 'F1F2F2 ' union all
select '101030 ', '1030 ', 'F1F3F3 ' union all
select '101020 ', '1030 ', 'F1F3F2 ' union all
select '102010 ', '1020 ', 'F1F2F1 ' union all
select '1020 ', '10 ', 'F1F2 '

GO

--广度搜索排序函数
CREATE FUNCTION f_Sort(@ID char(20)=NULL,@sort int=1)
RETURNS @t_Level TABLE(ID char(20),sort int)
AS
BEGIN
DECLARE tb CURSOR LOCAL
FOR
SELECT ID FROM tb
WHERE PID=@ID
OR(@ID is null AND PID = '000000 ')
order by id
OPEN TB
FETCH tb INTO @ID
WHILE @@FETCH_STATUS=0
BEGIN
INSERT @t_Level VALUES(@ID,@sort)
SET @sort=@sort+1
IF @@NESTLEVEL <32 --如果递归层数未超过32层(递归最大允许32层)
BEGIN
--递归查找当前节点的子节点
INSERT @t_Level SELECT * FROM f_Sort(@ID,@sort)
SET @sort=@sort+@@ROWCOUNT --排序号加上子节点个数
END
FETCH tb INTO @ID
END
RETURN
END
GO

--显示结果
SELECT a.*
FROM tb a,f_Sort(DEFAULT,DEFAULT) b
WHERE a.ID=b.ID
ORDER BY b.sort
go
drop table tb
drop function f_Sort
/*--结果
ID PID Name
-------------------- -------------------- ----------
10 000000 F1
1010 10 F1F1
102010 1010 F1F1F1
102010 1020 F1F2F1
102020 1010 F1F1F2
102020 1020 F1F2F2
1020 10 F1F2
102010 1010 F1F1F1
102010 1020 F1F2F1


102020 1010 F1F1F2
102020 1020 F1F2F2
1030 10 F1F3
101010 1030 F1F3F1
101020 1030 F1F3F2
101030 1030 F1F3F3

(15 row(s) affected)
--*/

热点排行
Bad Request.