在SQL Server 2005中循环而不使用Cursor

时间:2009-05-27 07:34:28

标签: sql-server-2005 tsql

我有一个像这样的表OrganisationStructure:

OrganisationID INT
ParentOrganisationID INT
OrganisationName VARCHAR(64)

1 | 0 | Company
2 | 1 | IT DIVISION 
3 | 2 | IT SYSTEM BUSINESS UNIT
4 | 1 | MARKETING DIVISION
5 | 4 | DONATION BUSINESS UNIT

我想要一个查询,如果通过的应用程序说OrganisatinID = 1意味着它将循环(查看父/子)直到此表的结尾并抓取所有可能的返回OrganisatioIDs = (1, 2, 3, 4, 5)

其他如果传递OrganisationID = 2,则返回OrganisationID = (2, 3)

其他如果传递OrganisationID = 3,则返回OrganisationID = 3

没有光标的任何想法吗?

由于

6 个答案:

答案 0 :(得分:2)

您可以使用SQL 2005 CTE使SQL引擎递归执行。

基本方法的列举在http://blogs.msdn.com/anthonybloesch/archive/2006/02/15/Hierarchies-in-SQL-Server-2005.aspx

Celko在SQL书中也有一棵树,涵盖所有这些到n度。

或者你可以通过选择每个级别到本地表变量然后循环,插入带有select的子项来强制它,直到你的@@ ROWCOUNT为零(即,你没有找到更多的孩子)。如果你没有很多数据,这很容易编码,但你暗示你正在通过说你不想要光标来寻找性能。

答案 1 :(得分:2)

declare @rootID int;
select @rootID = 4;
with cte_anchor as (
    SELECT OrganisationID
        , ParentOrganisationID
        , OrganisationName
    FROM Organisation
    WHERE OrganisationID = @rootID)
, cte_recursive as (
    SELECT OrganisationID
        , ParentOrganisationID
        , OrganisationName
    FROM cte_anchor
    UNION ALL
    SELECT o.OrganisationID
        , o.ParentOrganisationID
        , o.OrganisationName
    FROM Organisation o JOIN cte_recursive r
        ON o.ParentOrganisationID = r.OrganisationID)
SELECT * FROM cte_recursive

答案 2 :(得分:1)

在带有Common Table Expressions的SqlServer 2005中,可以执行递归查询。有关示例,请参阅4guysfromrolla的Common Table Expressions (CTE) in SQL Server 2005中的“递归公用表表达式”。

答案 3 :(得分:1)

您的父子结构可以达到多少级别?

您可以在桌面上进行自我加入以排列祖父母/父/子实体,但这受到父/子关系可以深入的级别数量的限制。

我知道你已经说过了SQL 2005但是你知道这种树结构映射正是Sql 2008中新的HierarchyIDVideo Here)的用途。

答案 4 :(得分:1)

使用简单的香草简单蛮力尝试3个级别 - 您可以根据需要添加级别。

SELECT DISTINCT OrganizationID  
FROM  
(  
    SELECT
    ParentOrganizationID  
    FROM OrganizationStructure  
    WHERE ParentOrganizationID = @arg  
    UNION ALL  

    SELECT  
    OrganizationID  
    FROM OrganizationStructure  
    WHERE ParentOrganizationID = @arg  

    UNION ALL

    SELECT os2.OrganizationID  
    FROM OrganizationStructure os  
    JOIN OrganizationStructure os2 ON os.OrganizationID = is2.ParentOrganizationID  
    WHERE os.ParentOrganizationID = @arg   
) data

答案 5 :(得分:1)

我相信这个问题得到了很好的回答,但是如果你对构建数据的替代方法感兴趣以获得更好的效果,请谷歌“推动使用分层数据的方法” 我暂时不允许发布链接:)