22,210
社区成员
发帖
与我相关
我的任务
分享
ID FID name
1 0 根节点
2 1 二级根节点
3 2 三级根节点
4 3 四级根节点
5 4 五级根节点
--参考一下实例
--> 生成测试数据表:tb
IF NOT OBJECT_ID('[tb]') IS NULL
DROP TABLE [tb]
GO
CREATE TABLE [tb](GUID INT IDENTITY,[col1] NVARCHAR(10),[col2] NVARCHAR(20))
INSERT [tb]
SELECT N'A','01' UNION ALL
SELECT N'B','01.01' UNION ALL
SELECT N'C','01.01.01' UNION ALL
SELECT N'F','01.01.01.01' UNION ALL
SELECT N'E','01.01.01.02' UNION ALL
SELECT N'D','01.01.01.03' UNION ALL
SELECT N'O','02' UNION ALL
SELECT N'P','02.01' UNION ALL
SELECT N'Q','02.01.01'
GO
--SELECT * FROM [tb]
-->SQL查询如下:
---另一种方法
;WITH T AS
(
SELECT *,PATH=CAST([COL1] AS VARCHAR(1000)) FROM TB A
WHERE NOT EXISTS(
SELECT 1 FROM TB
WHERE A.COL2 LIKE COL2+'%'
AND LEN(A.COL2)>LEN(COL2))
UNION ALL
SELECT A.*,CAST(PATH+'-->'+A.COL1 AS VARCHAR(1000))
FROM TB A
JOIN T B
ON A.COL2 LIKE B.COL2+'%'
AND LEN(A.COL2)-3=LEN(B.COL2)
)
SELECT * FROM T ORDER BY LEFT(COL2,2)
/*
GUID COL1 COL2 PATH
----------- ---------- -------------------- --------------------
1 A 01 A
2 B 01.01 A-->B
3 C 01.01.01 A-->B-->C
4 F 01.01.01.01 A-->B-->C-->F
5 E 01.01.01.02 A-->B-->C-->E
6 D 01.01.01.03 A-->B-->C-->D
7 O 02 O
8 P 02.01 O-->P
9 Q 02.01.01 O-->P-->Q
(9 行受影响)
*/
;WITH T AS
(
SELECT *,CAST(COL1 AS VARCHAR(1000)) AS PATH
FROM TB
WHERE COL2 NOT LIKE '%.%'
UNION ALL
SELECT A.*,CAST(B.PATH+'-->'+A.COL1 AS VARCHAR(1000))
FROM TB A,T B
WHERE A.COL2 LIKE B.COL2+'.[01-99][01-99]'
)
SELECT * FROM T
ORDER BY LEFT(COL2,2)
/*
GUID COL1 COL2 PATH
----------- ---------- -------------------- --------------------
1 A 01 A
2 B 01.01 A-->B
3 C 01.01.01 A-->B-->C
4 F 01.01.01.01 A-->B-->C-->F
5 E 01.01.01.02 A-->B-->C-->E
6 D 01.01.01.03 A-->B-->C-->D
7 O 02 O
8 P 02.01 O-->P
9 Q 02.01.01 O-->P-->Q
(9 行受影响)
*/
create table tb(ID int, FID int, name nvarchar(10))
insert into tb select 1,0,'根节点'
insert into tb select 2,1,'二级根节点'
insert into tb select 3,2,'三级根节点'
insert into tb select 4,3,'四级根节点'
insert into tb select 5,4,'五级根节点'
go
;with cte as(
select *,id as flg,CONVERT(nvarchar(50),name)n from tb where FID=0
union all
select b.*,a.flg,CONVERT(nvarchar(50),a.n+'/'+b.name) from cte a inner join tb b on a.ID=b.FID
)select n from cte a where not exists(select 1 from cte where flg=a.flg and n>a.n)
/*
n
--------------------------------------------------
根节点/二级根节点/三级根节点/四级根节点/五级根节点
(1 行受影响)
*/
go
drop table tb
if object_id('[TB]') is not null drop table [TB]
go
create table [TB] (ID int,FID int,name nvarchar(10))
insert into [TB]
select 1,0,'根节点' union all
select 2,1,'二级根节点' union all
select 3,2,'三级根节点' union all
select 4,3,'四级根节点' union all
select 5,4,'五级根节点'
select * from [TB]
;WITH CTE
AS(
SELECT CONVERT(VARCHAR(100),NAME) AS name,Fid,ID FROM TB WHERE FId = 0
UNION ALL
SELECT CONVERT(VARCHAR(100),CTE.NAME+'/'+TB.NAME) AS name,TB.FID,TB.ID FROM CTE INNER JOIN TB ON CTE.ID = TB.fid
)
SELECT TOP 1 name FROM CTE ORDER BY fid DESC
/*
根节点/二级根节点/三级根节点/四级根节点/五级根节点*/