有多个子代的递归CTE

时间:2018-09-12 15:52:20

标签: sql tsql recursion common-table-expression

我正在处理cte即时通讯问题。

首先,我创建了一个显示我遇到的问题的示例:

CREATE TABLE #ctetemp (ID int, ParentID int, Level int, Value float, Unit varchar(5), Name Varchar(150))

INSERT INTO #ctetemp (ID, ParentID, Level, Value, Unit, Name)
VALUES 
(50,21,4,7.15,'C','Name01'),
(306,106,6,7.15,'A','Name02'),
(307,106,6,2.86,'A','Name03'),
(308,106,6,7.15,'A','Name04'),
(309,106,6,14.3,'A','Name05'),
(310,106,6,2.86,'A','Name06'),
(311,106,6,2.86,'A','Name08'),
(312,107,6,14.3,'A','Name07'),
(313,107,6,28.6,'A','Name09'),
(314,107,6,28.6,'A','Name10'),
(315,107,6,34.32,'A','Name11'),
(338,112,6,28.6,'B','Name12'),
(339,112,6,14.3,'B','Name13'),
(340,112,6,14.3,'B','Name14'),
(341,112,6,14.3,'B','Name15'),
(342,113,6,71.5,'B','Name16'),
(372,118,6,14.3,'C','Name17'),
(373,118,6,14.3,'C','Name18'),
(375,118,6,14.3,'C','Name19'),
(375,118,6,42.9,'B','Name19'),
(414,122,6,14.3,'B','Name20'),
(415,122,6,14.3,'B','Name21'),
(416,122,6,14.3,'B','Name22'),
(417,122,6,14.3,'B','Name23'),
(418,122,6,14.3,'B','Name24'),
(419,122,6,14.3,'B','Name25'),
(500,131,6,7.15,'C','Name26'),
(938,193,6,7.15,'C','Name27'),
(1188,228,6,14.3,'C','Name28'),
(1285,244,6,14.3,'B','Name29'),
(1324,253,6,0,'C','Name30'),
(1327,253,6,42.9,'C','Name31'),
(1482,282,6,14.3,'C','Name32'),
(1548,1547,5,28.6,'A','Name33'),
(1561,1548,6,14.3,'A','Name34'),
(1601,106,6,28.6,'C','Name64'),
(1602,106,6,28.6,'C','Name35'),
(1603,106,6,28.6,'C','Name36'),
(1604,106,6,14.3,'C','Name37'),
(1689,118,6,14.3,'C','Name38'),
(1690,118,6,7.15,'C','Name62'),
(1819,131,6,7.15,'C','Name39'),
(1820,131,6,7.15,'C','Name40'),
(2281,193,6,7.15,'C','Name27'),
(2303,196,6,21.45,'A','Name41'),
(2304,196,6,28.6,'A','Name42'),
(2518,228,6,7.15,'C','Name63'),
(2539,231,6,7.15,'A','Name43'),
(3642,1548,6,42.9,'A','Name44'),
(21,10,3,0,NULL,'Name45'),
(106,36,5,0,NULL,'Name46'),
(107,37,5,0,NULL,'Name47'),
(112,40,5,0,NULL,'Name48'),
(113,41,5,0,NULL,'Name49'),
(118,44,5,0,NULL,'Name50'),
(122,46,5,0,NULL,'Name51'),
(131,50,5,0,NULL,'Name52'),
(228,80,5,0,NULL,'Name53'),
(253,93,5,0,NULL,'Name54'),
(282,102,5,0,NULL,'Name55'),
(40,17,4,0,NULL,'Name56'),
(41,17,4,0,NULL,'Name57'),
(44,19,4,0,NULL,'Name58'),
(46,19,4,0,NULL,'Name61'),
(17,8,3,0,NULL,'Name59'),
(19,9,3,0,NULL,'Name60')

;WITH CTE AS
(
   -- define the "anchor" query - select the chosen forum
   SELECT 
      f.id, f.Value, f.id as RootID, f.Unit, f.Level
   FROM #ctetemp f
   WHERE Level = 3
   UNION ALL
   -- select the child rows
   SELECT 
    f.id, f.value, cte.RootID, f.Unit, f.Level
    FROM #ctetemp f
    INNER JOIN CTE on f.ParentID = CTE.ID
)

SELECT * FROM CTE 
WHERE Unit IS NOT NULL
ORDER BY ID

DROP TAble #ctetemp

如您所见,我有一个表,每个ID可以包含多个条目。它是多个用户的答案列表。我想对这些答案进行分组,并在以后按级别和单位对它们的值求和。每个单元可以有多个用户,并且每个用户可以回答所有问题,如果可以的话:)。每个单元都有一个未定义的单位数和一个未定义的用户数。

在当前脚本中,所有来自单元A的答案都将丢失。我认为我需要CTE中的LEFT JOIN,但我不需要(因为在递归部分中禁止这样做)。

任何帮助将不胜感激

亲切的问候 卢卡斯

1 个答案:

答案 0 :(得分:0)

我不知道您是否简化了示例数据,但是查询不包含单元A是正确的。

根据示例数据,所有那些节点均未连接任何东西。它们只是悬空的分支。

例如:

  • 'A':306-> 106-> 36(不存在)。
  • 'A':3642-> 1548-> 1547(不存在)。
  • 'A':2304-> 196(不存在)。

无法从树的其余部分到达任何节点'A'。