用于选择子项的SQL查询

时间:2011-07-20 06:12:49

标签: sql sql-server-2008 recursion common-table-expression

我使用以下存储过程来选择给定单位id的所有子单元。对于each unit only one child,那里没有子单元

ALTER PROCEDURE [dbo].[UnitSelectChildByID] 
@company_ID INT,
@unit_ID INT

AS
BEGIN
DECLARE @parent INT
    SET @parent=@unit_ID
    DECLARE @temp TABLE(id int)
    WHILE((SELECT COUNT(*)  FROM tblUnit WHERE parent_ID=@parent) >0)
    BEGIN
    INSERT INTO @temp SELECT unit_ID FROM tblUnit WHERE parent_ID=@parent
    SET @parent=(SELECT unit_ID FROM tblUnit WHERE parent_ID=@parent) 
    END
    SELECT 
         unit_ID
         ,short_Name AS unit     
    FROM 
         tblUnit 
    WHERE 
        unit_ID IN (SELECT id FROM @temp) OR unit_ID=@unit_ID
END 

这是正常的。我想知道的是avoiding while loop and table variable

选择子单元的更好方法

3 个答案:

答案 0 :(得分:2)

看起来你正在使用递归,哪些CTE适合。

WITH Units (unit_ID, short_Name)
AS
(
    --initial select of the main parent
    Select unit_ID, short_Name
    From tblUnit
    Where unit_ID = @unit_ID

    Union All

    --plus the recursive self join of the sub units
    Select unit_ID, short_Name
    From tblUnit
    Inner Join Units On Units.unit_ID = tblUnit.parent_ID
)

Select unit_ID, short_Name
From Units

答案 1 :(得分:1)

您可以查看公用表格表达式 http://msdn.microsoft.com/en-us/library/ms186243.aspx

请注意,我实际上没有尝试过以下的SQL,我只修改了MSDN页面上的示例以使用您的表和列定义。

WITH UnitChildren (unit_ID, short_Name)
AS
(
-- Anchor member definition
    SELECT u.unit_ID, short_Name, 0 AS Level
    FROM tblUnit AS u
    WHERE unit_ID = @unit_ID
    UNION ALL
-- Recursive member definition
    SELECT u.unit_ID, short_Name, Level + 1
    FROM tblUnit AS u
    INNER JOIN UnitChildren AS uc
        ON u.unit_ID = uc.parent_ID
)

-- Statement that executes the CTE
SELECT * FROM UnitChildren 
GO

答案 2 :(得分:0)

如果设计层次结构中只有两个级别:

SELECT    u.unit_ID, u.short_Name
FROM      tblUnit AS u LEFT OUTER JOIN
              tblUnit AS p ON u.parent_ID = p.unit_ID
WHERE     ISNULL(u.parent_ID, u.unit_ID) = @unit_ID