Michelle Anne Rigor Ответов: 1

Найдите количество узлов-потомков в SQL-запросе


В настоящее время я создаю организационную диаграмму, и мне нужно общее количество всех узлов под определенным сотрудником.

Я исследовал, что мне нужно использовать рекурсивный SQL. Но, похоже, он не работает в моем запросе. Вместо этого я неоднократно (я знаю, что это кажется неправильным) помещаю запрос во временную таблицу и добавляю детей сотрудника и так далее. Есть примерные данные:
INSERT INTO @T (ID, name, AdvisorID) VALUES
(1,  'Euler', NULL),
(2,  'Lagrange', 1),
(3,  'Laplace', 1),
(4,  'Fourier', 2),
(5,  'Poisson', 2),
(6,  'Dirichlet', 4),
(7,  'Lipschitz', 6),
(8,  'Klein', 6),
(9,  'Lindemann', 8),
(10, 'Furtwangler', 8),
(11, 'Hilbert', 9),
(12, 'Taussky-Todd', 10);

SELECT ID
, name
, AdvisorID
, (SELECT COUNT(*) FROM @T WHERE AdvisorID = e.ID) AS ChildrenCount
INTO #Temp1
FROM @T e

SELECT *
, (SELECT ISNULL((SUM(ChildrenCount)+e.ChildrenCount),0) FROM #Temp1 WHERE AdvisorID = e.ID) AS Total
INTO #Temp2
FROM #Temp1 e

SELECT * 
, (SELECT ISNULL((SUM(Total)+e.ChildrenCount),0) FROM #Temp2 WHERE AdvisorID = e.ID AS Total2
INTO #finalTemp
FROM #Temp2 e

и так далее...

Спасибо за помощь. Я просто хочу оптимизировать свой повторяющийся код, потому что он будет слишком долго загружаться на страницу.

Что я уже пробовал:

Как узнать общее количество непосредственных потомков родителя в HierarchyID – SQLServerCentral[^]
postgresql - рекурсивный SQL - подсчет количества потомков в иерархической структуре - переполнение стека[^]

1 Ответов

Рейтинг:
4

0x01AA

В случае, если вы можете использовать CTE, то на основе этого: sql server - подсчет количества дочерних элементов в иерархических данных SQL - переполнение стека[^]

SQL lokks нравится

;WITH ChildrenCTE AS (
  SELECT  RootID = ID, ID
  FROM    Tbl1
  UNION ALL
  SELECT  cte.RootID, d.ID
  FROM    ChildrenCTE cte
          INNER JOIN Tbl1 d ON d.AdvisorID = cte.ID
)
SELECT  d.ID, d.AdvisorID, d.Name, cnt.Children
FROM    Tbl1 d
        INNER JOIN (
          SELECT  ID = RootID, Children = COUNT(*) - 1
          FROM    ChildrenCTE
          GROUP BY RootID
        ) cnt ON cnt.ID = d.ID
и вот результат, который я получаю:

ID  AdvisorID	Name		    Children
--  ---------	-------------	--------
1	NULL	Euler              11
2	1		Lagrange           9
3	1		Laplace            0
4	2		Fourier            7
5	2		Poisson            0
6	4		Dirichlet          6
7	6		Lipschitz          0
8	6		Klein              4
9	8		Lindemann          1
10	8		Furtwangler        1
11	9		Hilbert            0
12	10		Taussky-Todd       0


Michelle Anne Rigor

Спасибо Вам за это решение! Я застрял с этой проблемой. :)

0x01AA

Добро пожаловать.