计算子代节点[来自MySQL闭包模式]
我使用以下数据结构来表示数据的层次结构 用户表计算子代节点[来自MySQL闭包模式],mysql,hierarchical-data,Mysql,Hierarchical Data,我使用以下数据结构来表示数据的层次结构 用户表 +----+------+ | id | name | +----+------+ | 1 | Bob | | 2 | Sam | | 3 | Joe | | 4 | Kirk | | 5 | Greg | +----+------+ +----------+------------+-------+ | ancestor | descendant | depth | +----------+------------+------
+----+------+
| 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 |
+----------+------------+-------+
关系结束表
+----+------+
| 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 |
+----------+------------+-------+
以上数据代表以下内容(英语ese):
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 |
+----+------+------------------+
问题(最后)
有没有比我现有的更好的方法来计算总数?所有这些子选择都是粗略的
更新
+----+------+
| 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 |
+----------+------------+-------+
当我看到这一点时,我意识到,对于这个例子来说,我可能把事情简化得太多了。我有两个子选择做计数,因为我实际上有3个表:类别;项目;U类关闭。在我的示例数据中,显然不需要双嵌套子选择。在我的实际数据中有。希望这是有意义的。您不需要子查询。您可以通过再次加入闭包表来获得每个子节点的子节点数,以查找其祖先为相应子节点的所有节点。然后使用GROUPBY,这样就可以得到每个孩子的计数
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
您不需要子查询。您可以通过再次加入闭包表来获得每个子节点的子节点数,以查找其祖先为相应子节点的所有节点。然后使用GROUPBY,这样就可以得到每个孩子的计数
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
您不需要子查询。您可以通过再次加入闭包表来获得每个子节点的子节点数,以查找其祖先为相应子节点的所有节点。然后使用GROUPBY,这样就可以得到每个孩子的计数
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
您不需要子查询。您可以通过再次加入闭包表来获得每个子节点的子节点数,以查找其祖先为相应子节点的所有节点。然后使用GROUPBY,这样就可以得到每个孩子的计数
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
{拍头}。这么简单。谢谢你,比尔。昨晚我绊倒了自己,把事情弄得太难了。感谢你的回答。(旁注——我刚刚读了这篇文章,它太棒了。我正在窃取最上面的子弹清单){Head Slap}。这么简单。谢谢你,比尔。昨晚我绊倒了自己,把事情弄得太难了。感谢你的回答。(旁注——我刚刚读了这篇文章,它太棒了。我正在窃取最上面的子弹清单){Head Slap}。这么简单。谢谢你,比尔。昨晚我绊倒了自己,把事情弄得太难了。感谢你的回答。(旁注——我刚刚读了这篇文章,它太棒了。我正在窃取最上面的子弹清单){Head Slap}。这么简单。谢谢你,比尔。昨晚我绊倒了自己,把事情弄得太难了。感谢你的回答。(旁注——我刚刚读了这篇文章,它太棒了。我正在窃取顶部的子弹清单)