【发布时间】:2014-03-28 04:33:33
【问题描述】:
我认为这将更容易解释为一个故事而不是示例代码。
- 我有一张父母和孩子的表格。
- 父级可能是另一个父级的子级,依此类推。
- 有顶级父母。
- 兄弟姐妹是可能的(同一父母的两个或更多孩子)
我正在尝试在 SQL 中抓取此表并获取所有关系。
以下是关系如何运作的项目符号示例。
o 6220 (Top Level Parent)
- 6219 (Child1 of 6220)
- 6221 (Child2 of 6220)
* 6222 (Child1 of 6221/GrandChild1 of 6220)
* 6223 (Child2 of 6221/GrandChild2 of 6220)
x 6224 (Child1 of 6223/GrandChild1 of 6221/GreatGrandChild1 of 6220)
o 6225 (Top Level Parent)
这是表格形式的外观:
Parent, Child
NULL, 6220
6220, 6221
6220, 6219
6221, 6222
6221, 6223
6223, 6224
NULL, 6225
我正在寻找的(最佳)结果是:
Parent, Child, Level
6220, 6220, 0
6220, 6221, 1
6220, 6219, 1
6220, 6222, 2
6220, 6223, 2
6220, 6224, 4
6221, 6222, 1
6221, 6223, 1
6221, 6224, 2
6223, 6224, 1
6225, 6225, 0
我尝试了递归 CTE 和循环,我可以接近,但不完全。希望接近这个或类似的东西是有意义的。我想将其放入一个表中,我可以查询该表以查找父母或孩子的所有父母、祖父母、子女、孙子女等。兄弟姐妹关系并不重要。
感谢收看。如果我能澄清一下,请告诉我。
这是我一直在尝试的方法:
DECLARE @InsertedCount INT
DECLARE @RelationshipLevel TINYINT
DECLARE @AgyCount INT
DECLARE @LoopCount INT = 1
DECLARE @AgencyId INT
SELECT @AgyCount = COUNT(AgencyId) FROM dbo.Agency AS A
/* ==============================================================================
Get All AgencyIDs into a table with an incremented column
============================================================================== */
IF (OBJECT_ID('tempdb.dbo.#tmpAllAgy') > 0)
DROP TABLE #tmpAllAgy
CREATE TABLE #tmpAllAgy (tmpAllAgyId INT IDENTITY(1,1) PRIMARY KEY, AgencyId INT)
INSERT INTO #tmpAllAgy (AgencyId)
SELECT AgencyId FROM dbo.Agency ORDER BY AgencyId
/* ==============================================================================
Temp table for the results of the matrix to compare to physical table
============================================================================== */
IF (OBJECT_ID('tempdb.dbo.#ChildAgencies') > 0)
DROP TABLE #ChildAgencies
CREATE TABLE #ChildAgencies (LoopOrder INT, ParentAgencyId INT, ChildAgencyId INT, RelationshipLevel TINYINT)
/* ==============================================================================
Outer loop to get the next Agency Id from Temp Table
============================================================================== */
WHILE @LoopCount <= @AgyCount
BEGIN
SET @RelationshipLevel = 0
SELECT @AgencyId = AgencyId FROM #tmpAllAgy WHERE tmpAllAgyId = @LoopCount
INSERT INTO #ChildAgencies(LoopOrder, ParentAgencyId, ChildAgencyId, RelationshipLevel)
SELECT @LoopCount, NULL, AgencyId, @RelationshipLevel
FROM dbo.Agency
WHERE AgencyId = @AgencyID
SET @InsertedCount = 1--@@ROWCOUNT
/* ==============================================================================
Inner loop to create the hierarchy for each AgencyId
============================================================================== */
WHILE @InsertedCount > 0
BEGIN
SET @InsertedCount = NULL
SET @RelationshipLevel = @RelationshipLevel + 1
INSERT INTO #ChildAgencies (LoopOrder, ParentAgencyId, ChildAgencyId, RelationshipLevel)
SELECT @LoopCount, @AgencyId, AgencyId, @RelationshipLevel
FROM dbo.Agency
WHERE AgencyId NOT IN (SELECT ChildAgencyId FROM #ChildAgencies)
AND ParentAgencyId IN (SELECT ChildAgencyId FROM #ChildAgencies)
AND StatusCode <> 109 /*QA-Deleted*/
SET @InsertedCount = @@ROWCOUNT
END
SET @LoopCount = @LoopCount + 1
END
递归 CTE 似乎只带来直接的父母和孩子,同时任意增加计数。 上面的循环代码很接近,但似乎以奇怪的顺序做事。
【问题讨论】:
-
示例代码中的“LoopOrder”仅用于故障排除。我正在验证循环的循环顺序。作为一个领域,它是无关紧要的。
标签: sql loops recursion hierarchy recursive-query