当我在Oracle商店工作时,我认为CONNECT_BY是理所当然的。现在我不得不使用SQL Server 2005并且有一些讨厌的对象层次结构。具体来说,我们有一个自引用表,其中所有子记录都有一个父级id列。目前,我们有一个视图,将子映射映射到层次结构中的级别,以及一个令人讨厌的查询,它将父母与子女联系起来。虽然这种方法有效,但它远非优雅和臭味。我只是好奇其他人如何从SQL Server 2005中检索分层数据。
答案 0 :(得分:25)
这将创建典型的分层表,并使用CTE选择层次结构并为每个项创建路径。
CREATE TABLE tblHierarchy (ID int, ParentID int NULL, Name varchar(128));
INSERT INTO tblHierarchy VALUES (1, NULL, '1');
INSERT INTO tblHierarchy VALUES (2, NULL, '2');
INSERT INTO tblHierarchy VALUES (3, NULL, '3');
INSERT INTO tblHierarchy VALUES (4, 1, '1.1');
INSERT INTO tblHierarchy VALUES (5, 1, '1.2');
INSERT INTO tblHierarchy VALUES (6, 4, '1.1.1');
WITH Parent AS
(
SELECT
ID,
ParentID,
Name AS Path
FROM
tblHierarchy
WHERE
ParentID IS NULL
UNION ALL
SELECT
TH.ID,
TH.ParentID,
CONVERT(varchar(128), Parent.Path + '/' + TH.Name) AS Path
FROM
tblHierarchy TH
INNER JOIN
Parent
ON
Parent.ID = TH.ParentID
)
SELECT * FROM Parent
输出:
ID ParentID Path
1 NULL 1
2 NULL 2
3 NULL 3
4 1 1/1.1
5 1 1/1.2
6 4 1/1.1/1.1.1
答案 1 :(得分:3)
仅供参考。 SQL Server 2008支持新数据类型Hierarchy ID。
答案 2 :(得分:3)
使用两者后,我发现CONNECT BY比CTE更灵活,更易于使用。问题与我几周前回答的问题没有什么不同。有关使用CTE的查询示例,请参阅Here以获取CONNECT BY和CTE以及Here的简要比较。
答案 3 :(得分:2)
答案 4 :(得分:1)
答案 5 :(得分:0)
首先遍历层次结构的深度,然后是下一个兄弟级别, 可以使用CTE:
declare @tempTable TABLE
(
ORGUID int,
ORGNAME nvarchar(100),
PARENTORGUID int,
ORGPATH nvarchar(max)
)
;WITH RECORG(ORGuid, ORGNAME, PARENTORGUID, ORGPATH)
as
(
select
org.UID,
org.Name,
org.ParentOrganizationUID,
dbo.fGetOrganizationBreadcrumbs(org.UID)
from Organization org
where org.UID =1
union all
select
orgRec.UID,
orgRec.Name,
orgRec.ParentOrganizationUID,
dbo.fGetOrganizationBreadcrumbs(orgRec.UID)
from Organization orgRec
inner join RECORG recOrg on orgRec.ParentOrganizationUID = recOrg.ORGuid
)
insert into @tempTable(ORGUID, ORGNAME, PARENTORGUID,ORGPATH)
select ORGUID, ORGNAME, PARENTORGUID,ORGPATH
from RECORG rec
select *
from @tempTable where ORGUID in(select MIN(tt.ORGUID)
from @tempTable tt
group by tt.PARENTORGUID)