2011-07-20 52 views
1

使用以下存储过程来选择给定单位id的所有子单元。对于each unit only one child是没有子单元用于选择子的SQL查询

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

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

这是正常工作。我想知道更好的方法是由avoiding while loop and table variable

选择子单位

回答

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

你可以看看通用表表达式 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 
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 
+0

不工作,查询选择其他家庭的孩子也...... – Nithesh

+0

替换'ISNULL(p.parent_ID,@unit_ID) '用'ISNULL(u.parent_ID,u.unit_ID)''。对错误抱歉。 –

+0

:agian错了..它只返回第一个孩子。 – Nithesh