Ускорить T- SQL CTE, перестраивая только ту часть дерева, которую вы хотите? - PullRequest
0 голосов
/ 15 февраля 2020

У меня есть очень простая таблица ParentID (int) и ChildID (int). Проблема в том, что это несколько тысяч строк, и многие из ChildID являются ParentID других ParentID.

Все, что меня интересует, - это построение иерархии всех этих общих идентификаторов. Тем не менее, некоторые ветви могут иметь глубину только 2 или 3 уровня, в то время как другие могут иметь глубину go 30+.

Хотя важны все данные, важны только определенные ветви (и их дочерние ветви). особые времена.

Моя первоначальная попытка состояла в том, чтобы просто «перебить» его и построить целое дерево, но оно невероятно неэффективно и требовало значительных ресурсов.

Поэтому мне было интересно, как я могу настроить свою базу c очень простой / стандартный CTE (использующий вышеупомянутую простую таблицу только с двумя целочисленными столбцами), чтобы выбрать конкретную ветвь этого очень сложного дерева и просто рекурсивно построить иерархию только той ветви, которую я хочу, до самой далекой точки, не имея построить остальную часть дерева и все его ветви.

Возможно ли это?

В качестве дополнительного примечания - из-за огромного объема данных в сочетании с его простотой только числа c данных, у меня нет возможности угадать, что будет после определенной ветви (т. Е. Нет Эквенциальная нумерация или что-либо, что дает подсказки, в основном все, что может быть за пределами ветви, которую я хочу, я знаю, что мне нужно извлечь из всех данных, я просто не хочу тратить время / ресурсы на создание веток, которые мне не нужны ).

РЕДАКТИРОВАТЬ: Вот мой пример кода:

;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

Насколько данные, родительский идентификатор и дочерний идентификатор являются целыми числами от 1 до 10 000. У некоторых родителей есть дети, у некоторых их нет (ChildID равен нулю в этих случаях).

Поэтому мой вывод выглядит следующим образом:

ParentID> ID> ID> ID> ID> ID> ChildID (где идентификаторы в середине - это дети их родителей, а затем родители последующих детей и т. д.).

1 Ответ

1 голос
/ 15 февраля 2020

Итак, вот код, который я использовал, чтобы решить мою проблему, чтобы выбрать идентификатор с номером 2220, который является моим «магистральным» путем, и я смог отобразить этот идентификатор через все идентификаторы «Родитель / ребенок» на самых дальних листьях. из моих ветвей иерархии.

Теперь я вообще не эксперт в SQL кодировании. Честно говоря, я даже не очень хорош в этом, так что, возможно, это не лучший способ исправить проблему (или даже полностью исправить, но, учитывая то, что я ожидал для результатов, похоже, это работает для меня).

Теперь, если 2220 не был ChildID другого ParentID, я не уверен, будет ли это работать. Я могу проверить это позже, но в настоящее время я получаю необходимые данные. Однако, если это оказывается проблемой, я всегда могу сделать проверку и вставить его в качестве ChildID с ParentID 0 (поскольку я знаю, что все мои идентификаторы являются положительными целыми числами).

Независимо от того, это как я изменил свой код, чтобы он работал для меня:

;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'

Теперь, если есть кто-то с опытом, который мог бы прокомментировать качество этого «исправления» и если это разумно (или если я Я что-то упустил), я был бы признателен. Я не хочу случайно отравить массы дерьмовым исправлением из-за моей наивности, полагая, что это хорошее (достаточно) исправление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...