【发布时间】:2016-03-15 00:51:13
【问题描述】:
我正在使用城市、国家和大洲的示例层次结构试验 SQL 公用表表达式,以及访问过和未访问过的示例。
表格t_hierarchy 如下所示:
(注意:visited 列对于非城市故意为 NULL,因为我希望这是一个动态计算的百分比。)
然后我使用下面的 SQL 根据t_hierarchy 中的数据创建了一个递归结果集:
WITH myCTE (ID, name, type, parentID, visited, Depth)
AS
(
Select ID, name, type, parentID, visited, 0 as Depth From t_hierarchy where parentID IS NULL
UNION ALL
Select t_hierarchy.ID, t_hierarchy.name, t_hierarchy.type, t_hierarchy.parentID, t_hierarchy.visited, Depth + 1
From t_hierarchy
inner join myCte on t_hierarchy.parentID = myCte.ID
)
Select ID, name, type, parentID, Depth, cnt.numDirectChildren, visited
FROM myCTE
LEFT JOIN (
SELECT theID = parentID, numDirectChildren = COUNT(*)
FROM myCTE
GROUP BY parentID
) cnt ON cnt.theID = myCTE.ID
order by ID
结果如下:
我现在想做的,我正在努力的,是创建一个列,例如visitedPercentage 显示层次结构中每个“级别”的访问过的城市百分比(根据国家和大洲对城市进行不同的处理)。解释一下,沿着“树”往上走:
- 马德里将是 100%,因为它已被访问过 (
visited= 1) - 巴塞罗那将是 0%,因为它没有被访问过 (
visited= 0) - 因此西班牙将是 50%,因为它有 2 个直系子女,一个是 100%,另一个是 0%
- 因此欧洲为 50%,因为西班牙为 50%,法国为 100%(访问过巴黎),德国为 0%(未访问过柏林)
我希望这是有道理的。我有点想说“如果它不是城市,请根据所有直系子女的visitedPercentage 计算出这个级别的visitedPercentage,否则只显示 100% 或 0%。任何非常感谢您的指导。
更新: 我已经设法使用Daniel Gimenez 的建议进一步推进到法国 100、西班牙 50 等。但顶级项目(例如欧洲)仍然是 0,如下所示:
我认为这是因为计算是在查询的递归部分之后完成的,而不是在其中。 IE。这一行:
SELECT... , visitPercent = SUM(CAST visited AS int) / COUNT(*) FROM myCTE GROUP BY parentID
说“查看visited 列的子对象,计算值的总和,并将结果显示为visitPercent”,而应该说“查看现有的visitPercent 值先前的计算”,如果这有意义的话。我不知道从这里去哪里! :)
【问题讨论】:
-
嘿@valoulkh 我没有时间处理这个问题,但是您需要第二个递归 CTE,它使用 myCTE 来得出每个层次结构中的所有相关城市。
SELECT ID, parentID FROM... UNION ALL SELECT ID, [parent's parentID] FROM newCTE INNER JOIN myCTE -
没问题,感谢您迄今为止的帮助。我会尝试按照你的逻辑:)
标签: sql sql-server-2008 common-table-expression hierarchical-data