【发布时间】:2016-09-04 03:53:52
【问题描述】:
我有这个父表。我的目标是找出一个 id 的所有后代。 例如下表:
+----------+-----+
| parentId | id |
+----------+-----+
| 0 | 1 |
| 0 | 2 |
| 0 | 3 |
| 0 | 4 |
| 1 | 5 |
| 1 | 11 |
| 5 | 12 |
| 12 | 13 |
| 14 | 15 |
| 19 | 20 |
| 20 | 24 |
+----------+-----+
给定父母 0 我想得到:
+----+
| Id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 11 |
| 12 |
| 13 |
+----+
我的限制/注释: 1. 在最坏的情况下,我可以有 4 个层次结构。 2.我的数据库是MYSQL(这意味着我不能写递归查询)。 3. id_to_id 表很小.. 100 行顶部。
我正在考虑的解决方案是这样的 sql 查询:
SELECT DISTINCT(T.Id)
FROM(
SELECT t1.Id
FROM id_to_id AS t1
LEFT JOIN id_to_id AS t2 ON t2.parentId = t1.Id
LEFT JOIN id_to_id AS t3 ON t3.parentId = t2.Id
LEFT JOIN id_to_id AS t4 ON t4.parentId = t3.Id
WHERE t1.parentId = 0
UNION ALL
SELECT t2.Id as lev2
FROM id_to_id AS t1
LEFT JOIN id_to_id AS t2 ON t2.parentId = t1.Id
LEFT JOIN id_to_id AS t3 ON t3.parentId = t2.Id
LEFT JOIN id_to_id AS t4 ON t4.parentId = t3.Id
WHERE t1.parentId = 0
UNION ALL
SELECT t3.Id as lev3
FROM id_to_id AS t1
LEFT JOIN id_to_id AS t2 ON t2.parentId = t1.Id
LEFT JOIN id_to_id AS t3 ON t3.parentId = t2.Id
LEFT JOIN id_to_id AS t4 ON t4.parentId = t3.Id
WHERE t1.parentId = 0
UNION ALL
SELECT t4.Id as lev4
FROM id_to_id AS t1
LEFT JOIN id_to_id AS t2 ON t2.parentId = t1.Id
LEFT JOIN id_to_id AS t3 ON t3.parentId = t2.Id
LEFT JOIN id_to_id AS t4 ON t4.parentId = t3.Id
WHERE t1.parentId = 0) as T
WHERE T.Id IS NOT NULL;
但是内部查询将被执行 4 次(我错了吗?):
FROM id_to_id AS t1
LEFT JOIN id_to_id AS t2 ON t2.parentId = t1.Id
LEFT JOIN id_to_id AS t3 ON t3.parentId = t2.Id
LEFT JOIN id_to_id AS t4 ON t4.parentId = t3.Id
WHERE t1.parentId = 0) as T
所以我的问题是:
- 有什么想法可以让它在不加入 4 次的情况下工作吗?或其他 该查询的智能解决方案?
- 如何编写可以在没有给定参数的情况下对表上的每个 id 执行相同的查询(我可以这样做吗?) - 类似于:
+----+------------+ | Id | decedents | +----+------------+ | 0 | 1,2,3,4,...| | 1 | 5,11,... | +----+------------+
谢谢, 伊多
【问题讨论】:
-
这篇文章似乎适合你:stackoverflow.com/questions/10646833/…干得好! ;)
-
您是否坚持只使用 SQL 来完成这项工作?我在项目的无限层次结构中遇到了类似的问题,发现它在我最终用于前端的语言中的程序代码非常干净。如果有兴趣,我会发布该解决方案。