Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过只重建所需树的一部分来加速T-SQL CTE?_Sql_Common Table Expression - Fatal编程技术网

通过只重建所需树的一部分来加速T-SQL CTE?

通过只重建所需树的一部分来加速T-SQL CTE?,sql,common-table-expression,Sql,Common Table Expression,我有一个非常简单的ParentID int和ChildID int表。问题是它有几千行长,许多ChildID是其他ParentID的ParentID 我感兴趣的是构建所有这些共享ID的层次结构。然而,一些分支可能只有2或3层深,而其他分支可能有30+层深 虽然所有数据都很重要,但在特定时间,只有某些分支机构及其分支机构才是重要的 我最初的尝试是“蛮力”它并构建整个树,但它效率低下且资源密集 所以,,我想知道我如何使用前面提到的简单表和两个整数列来调整我的基本的非常简单/标准CTE,以选择这个非常

我有一个非常简单的ParentID int和ChildID int表。问题是它有几千行长,许多ChildID是其他ParentID的ParentID

我感兴趣的是构建所有这些共享ID的层次结构。然而,一些分支可能只有2或3层深,而其他分支可能有30+层深

虽然所有数据都很重要,但在特定时间,只有某些分支机构及其分支机构才是重要的

我最初的尝试是“蛮力”它并构建整个树,但它效率低下且资源密集

所以,,我想知道我如何使用前面提到的简单表和两个整数列来调整我的基本的非常简单/标准CTE,以选择这个非常复杂的树的一个特定分支,并递归地构建我想要的分支的层次结构,直到它的最远点,而不必构建树的其余部分和所有部分它的分支

这可能吗

作为旁注-由于数据量巨大,加上它只是数字数据的简单性,我无法猜测某个分支之后会发生什么,即没有顺序编号或任何提供提示的内容,基本上任何内容都可能超出我想知道的分支我需要从所有数据中提取,我只是不想浪费时间/资源建立我不需要的分支机构

编辑:以下是我的示例代码:

;WITH CTE
AS (
Select ChildID
    ,ParentID
    ,cast(ParentID as varchar(max)) as IDpath
From #TempTable

UNION ALL

Select B.ChildID
    ,B.ParentID
    ,cast(B.ParentID as varchar(max)) + '>' + A.IDpath as IDpath
From CTE A
    Inner Join #TempTable B on A.ParentID=B.ChildID
)
Select Distinct IDpath
From CTE
Where IDpath is not null
就数据而言,父ID和子ID是1-10000之间的整数。有些父母有孩子,有些父母没有孩子,在这些情况下,孩子ID为空

因此,我的输出如下所示:


< PARTED> ID> ID> ID> ID> ID> Id>CHILDID,中间ID是父代的子女,然后是后续子代的父类等等。

< P>,这里是我用来修复问题的代码,ID为2220,是我的主干路径,我能够通过所有的父/子ID将该ID映射到我的等级体系分支中最远的叶子

现在我根本不是SQL编码方面的专家。坦率地说,我甚至不擅长这一点,因此这可能不是解决问题的最佳方式,甚至不是一个完全解决问题的方式,但考虑到我对结果的预期,这似乎对我有效

现在,如果2220不是另一个ParentID的ChildID,我不确定这是否有效。我可能会在以后测试,但现在,我得到了我需要的数据。然而,如果这最终成为一个问题,我总是可以做一个检查,并将其作为ParentID为0的ChildID插入,因为我知道我的所有ID都是正整数

不管怎样,我就是这样修改代码使其适合我的:

;WITH CTE
AS (
Select 1 as Level
    ,ChildID
    ,ParentID
    ,cast(ChildID as varchar(max)) as IDpath
From #TempTable

UNION ALL

Select Level + 1 as Level
    ,B.ChildID
    ,B.ParentID
    ,A.IDpath + '>' + cast(B.ChildID as varchar(max)) as IDpath
From CTE A
    Inner Join #TempTable B on A.ChildID=B.ParentID
Where Level = 1
    or (Level > 1 and IDpath like '2220%')
)
Select Distinct IDpath
From CTE
Where left(IDPath,4) = '2220'

现在,如果有专业人士可以评论此修复的质量,如果它是合理的,或者如果我遗漏了什么,我将不胜感激。我不想意外地用一个垃圾补丁毒害大众,因为我天真地认为这是一个足够好的补丁。

没有样本数据、预期结果和定义良好的问题陈述,这个问题相当理论化。我找到了我的解决方案。它基本上是在逆转CTE。上面的查询是在构建一棵树,或者说,它更像是一片从树叶到树干的森林。通过颠倒CTE的组装方式,我从主干构建到叶子,并且可以识别我想要的分支到叶子,而上面的查询只能从我的分支构建到主干,而叶子对我想要识别的东西没有用处。等我有更多时间后,我会发布解决方案。我是正确的,如果我要查找的ID不是另一个ParentID的ChildID,则此过程将失败。因此,我在我的数据中利用我上面的建议修复了这个问题,我的ID是正整数,并且我添加了一个insert语句来插入我正在寻找的任何/所有具有ParentID为0的ID,以缓解这个问题。