【发布时间】:2018-04-18 15:21:06
【问题描述】:
我在 SQL 数据库中有父子树关系。有许多表包含我所有的数据/关系,为此我需要的重要数据在下表中,我正在使用递归 CTE 查询来获取它。我的应用程序和数据库设计非常适合我正在做的事情。我需要进行一些管理/维护以确认数据是否正确,并且我正在尝试做的事情概述如下:
我的数据集包含的是: - FilterID - 这是父记录 ID - 深度 - 在我的 CTE 中,这给了我该树关系的记录数。 - sortCol - 在我的 CTE 中,我正在构建它(这只是所有 FilterID 的组合二进制字符串) - TreeListOfFilterIDs - 这是此级别记录的树中所有 FilterID 的列表。 - 我想要的结果 - 这是我添加的一列,用于标识我想从数据集中返回的字段列表
在本例中,FilterID 35 是起始记录。父子关系可以有 1 个父节点和 2 个(或更多)不同的子路径,因此 1 个父节点可以有 2 个或更多不同的子节点。注意:这种关系是有意的,因为 1 个父母可以有 2 个不同的孩子,我在我的代码/流程中使用它。
我需要从下面的数据集中得到的是只返回每个节点中父/子关系的最终路径的记录。我在下面的数据中添加了一个我没有从我的查询中获得的名为“我想要的结果”的列,我只想获取其中包含“X”的记录。
我正在填充表格,并且我的代码/流程正在使用我设计所有内容的方式。我现在尝试用这个逻辑完成的是找到唯一的最终路径,这样我就可以轻松识别每条最终路径并确保它们是正确的。这将用于维护目的,以监控数据和路径。
FilterID depth sortCol TreeListOfFilterIDs RESULTS I WANT
35 0 0x00000023 35
36 1 0x0000002300000024 35,36
37 2 0x000000230000002400000025 35,36,37
39 3 0x00000023000000240000002500000027 35,36,37,39 X
38 2 0x000000230000002400000026 35,36,38
40 3 0x00000023000000240000002600000028 35,36,38,40
44 4 0x000000230000002400000026000000280000002C 35,36,38,40,44 X
41 3 0x00000023000000240000002600000029 35,36,38,41
45 4 0x000000230000002400000026000000290000002D 35,36,38,41,45 X
42 3 0x0000002300000024000000260000002A 35,36,38,42
46 4 0x0000002300000024000000260000002A0000002E 35,36,38,42,46 X
43 3 0x0000002300000024000000260000002B 35,36,38,43
47 4 0x0000002300000024000000260000002B0000002F 35,36,38,43,47
48 5 0x0000002300000024000000260000002B0000002F00000030 35,36,38,43,47,48 X
49 5 0x0000002300000024000000260000002B0000002F00000031 35,36,38,43,47,49 X
请注意,以上数据来自我的 CTE 结果,但按 sortcol 值排序(因此这不是数据插入 CTE 的顺序)。
生成上述结果的SQL:
-- this combines the required answers for the next questions to display (will join to what is filled out in the form
IF OBJECT_ID('tempdb..#RequiredAnswersToFindNextFiltersToDisplay') IS NOT NULL
DROP TABLE #RequiredAnswersToFindNextFiltersToDisplay
CREATE TABLE #RequiredAnswersToFindNextFiltersToDisplay (
FilterID INT,
FormAssociationID INT,
RequiredAnswerFilterID INT
)
-- this gets the RequiredAnswersIntoA String for joining on
INSERT INTO #RequiredAnswersToFindNextFiltersToDisplay (
FilterID, FormAssociationID, RequiredAnswerFilterID
)
VALUES
( 35, 1, 0 ),
( 36, 2, 35 ),
( 37, 3, 36 ),
( 38, 4, 36 ),
( 39, 5, 37 ),
( 40, 6, 38 ),
( 41, 7, 38 ),
( 42, 8, 38 ),
( 43, 9, 38 ),
( 44, 10, 40 ),
( 45, 11, 41 ),
( 46, 12, 42 ),
( 47, 13, 43 ),
( 48, 14, 47 ),
( 49, 15, 47 )
;WITH ItemDataCTE(FilterID, FormAssociationID, RequiredAnswerFilterID, depth, sortcol, TreeListOfFilterIDs)
AS (
-- anchor member
SELECT FilterID, FormAssociationID, RequiredAnswerFilterID, 0, CAST(FilterID AS VARBINARY(900)) AS SortCol,
CAST(FilterID AS VARCHAR(MAX)) AS TreeListOfFilterIDs
FROM #RequiredAnswersToFindNextFiltersToDisplay
WHERE RequiredAnswerFilterID = 0
UNION ALL
SELECT ID.FilterID, ID.FormAssociationID, ID.RequiredAnswerFilterID, M.depth + 1, CAST(M.SortCol + CAST(ID.FilterID AS BINARY(4)) AS VARBINARY(900)) SortCol,
CAST(M.TreeListOfFilterIDs + ',' + CAST(ID.FilterID AS VARCHAR(50)) AS VARCHAR(MAX)) AS TreeListOfFilterIDs
FROM #RequiredAnswersToFindNextFiltersToDisplay ID
INNER JOIN ItemDataCTE AS M ON ID.RequiredAnswerFilterID = M.FilterID
)
SELECT *
FROM ItemDataCTE
ORDER BY ItemDataCTE.sortcol
【问题讨论】:
-
请edit您的问题将示例数据包含为 DDL+DML。最好能显示源表(我想你现在显示的是递归 cte 的结果)
-
很高兴您展示了 DDL,但我们仍然需要示例数据。请完成插入语句,以便我们将问题中的代码复制到测试环境中。
-
@Zohar Peled 对此表示抱歉,已更新为包含数据插入
标签: sql-server recursion parent-child