繁体   English   中英

SQL Server 2005 中的分层查询

[英]Hierarchical Queries in SQL Server 2005

当我在 Oracle 商店工作时,我认为 CONNECT_BY 是理所当然的。 现在我被困在使用 SQL Server 2005 并且有一些讨厌的对象层次结构。 具体来说,我们有一个自引用表,其中所有子记录都有一个带有其父 ID 的列。 目前,我们有一个视图将孩子映射到层次结构中的级别,还有一个讨厌的查询,可以完成繁重的工作以将父母与孩子联系起来。 虽然这种方法有效,但它远非优雅和臭味。 我只是好奇其他人如何从 SQL Server 2005 中检索分层数据。

这将创建典型的分层表,并使用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

OUTPUT:

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

仅供参考。 SQL Server 2008支持新的数据类型层次结构ID

使用两者后,我发现CONNECT BY比CTE更灵活,更易于使用。 问题与我几周前回答的问题没有什么不同。 有关使用CTE的查询示例,请参阅此处以获取CONNECT BY和CTE以及此处的简要比较。

读这个:

http://www.sitepoint.com/article/hierarchical-data-database/2/

它应该给你一些想法......

在SQL Server 2005中,您可以使用公用表表达式(CTE)。

要首先遍历层次结构的深度,然后是下一个兄弟级别,可以使用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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM