我正在使用以下数据结构来表示数据层次结构。
用户表
+----+------+
| id | name |
+----+------+
| 1 | Bob |
| 2 | Sam |
| 3 | Joe |
| 4 | Kirk |
| 5 | Greg |
+----+------+
关系关闭表
+----------+------------+-------+
| ancestor | descendant | depth |
+----------+------------+-------+
| 1 | 1 | 0 |
| 1 | 2 | 1 |
| 1 | 3 | 2 |
| 1 | 4 | 2 |
| 1 | 5 | 3 |
| 2 | 2 | 0 |
| 2 | 3 | 1 |
| 2 | 4 | 1 |
| 2 | 5 | 2 |
| 3 | 3 | 0 |
| 4 | 4 | 0 |
| 4 | 5 | 1 |
| 5 | 5 | 0 |
+----------+------------+-------+
以上数据表示以下内容(英语-英语):
鲍勃有一个儿子:山姆
山姆有两个儿子:乔和柯克。
乔没有儿子。
柯克有一个儿子:格雷格。
我从以下SQL获取给定用户的儿子:
SELECT u.*
FROM closure AS c
INNER JOIN `user` AS u ON (u.id = c.descendant)
WHERE c.ancestor = 1 AND c.depth = 1
这很好。但是我也想返回树下所有后代的数量。到目前为止,我能想到的最好的方法是:
SELECT
u.*,
(
SELECT COUNT(id) FROM `user` WHERE id IN (
SELECT descendant FROM closure
WHERE ancestor = c.descendant
)
) AS descendant_count
FROM closure AS c
INNER JOIN `user` AS u ON (u.id = c.descendant)
WHERE c.ancestor = 1 AND c.depth = 1
上述查询的预期输出为:
+----+------+------------------+
| id | name | descendant_count |
+----+------+------------------+
| 2 | Sam | 3 |
+----+------+------------------+
问题(最后)
是否有比我现有的方法更好的总数?所有这些子选择都是总的。
更新资料
我意识到,我可能对此示例进行了太多简化。我有两个子选择来进行计数,因为我实际上有3个表:category;项目; category_closure。在我的示例数据中,显然不需要双重嵌套子选择。在我的实际数据中。希望这是有道理的。
最佳答案
您不需要子查询。您可以通过再次连接到闭合表来获得每个子代的子代数,以查找其祖先是相应子代的所有那些节点。然后使用GROUP BY,这样您可以获得每个孩子的计数。
SELECT
u.*,
COUNT(*) AS descendant_count
FROM closure AS c
INNER JOIN `user` AS u ON (u.id = c.descendant)
INNER JOIN closure AS d ON (c.descendant = d.ancestor)
WHERE c.ancestor = 1 AND c.depth = 1
GROUP BY c.descendant
关于mysql - 计算后代节点[来自MySQL闭合模式],我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28204378/