我使用以下存储过程来选择给定单位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
答案 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