2011-07-20 53 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