考虑以下内容:
Table - id, parentid
我想做的是,我想拉一个特定父母的所有孩子(不仅是直接的孩子,还有他们所有的孩子,即孩子的孩子的孩子等等)。
假设该表包含以下行:(2, 1), (3, 1), (4, 2), (5, 4)
然后,对于parentid=1,表将返回id 2、3、4和5。
这可能吗?
如果没有(我想这确实不可能),我有什么选择?
我真的不想使用几十个查询。。。
附言:我无法更改数据库结构。
此外,由于表中可能有数十万条记录,我可以将它们全部提取出来,并使用PHP完成整个过程。
这可能会有所帮助:
$parentId = 1; // the parent id
$arrAllChild = Array(); // array that will store all children
while (true) {
$arrChild = Array(); // array for storing children in this iteration
$q = 'SELECT `id` FROM `table` WHERE `parentid` IN (' . $parentId . ')';
$rs = mysql_query ($q);
while ($r = mysql_fetch_assoc($rs)) {
$arrChild[] = $r['id'];
$arrAllChild[] = $r['id'];
}
if (empty($arrChild)) { // break if no more children found
break;
}
$parentId = implode(',', $arrChild); // generate comma-separated string of all children and execute the query again
}
print_r($arrAllChild);
您也可以使用递归来实现这一点,但我认为以上内容需要更少的迭代。
希望它能有所帮助!
EDIT-我忘了提一下,除了不能使用Arrays之外,您还可以在MySQL存储过程中实现相同的逻辑。上面的例子是在PHP中实现的,您可能已经猜到
不是一步到位。
我使用PHP在MySQL中进行了递归查询。。。循环通过一个级别,收集数据,修改查询以使用上次迭代中返回的结果,再次运行查询,等等。
Mysql对这种事情不是很友好。MSSQL、Oracle或PostgreSQL支持单一查询格式。
下面是我刚才针对类似问题编写的一个查询:
select if(e.id is not null, e.id, if(d.id is not null, d.id, if(c.id is not null, c.id, if(b.id is not null, b.id, a.id)))) as ID
from groups a
left join groups b on b.parent = a.id
left join groups c on c.parent = b.id
left join groups d on d.parent = c.id
left join groups e on e.parent = d.id
where a.parent = SOMETOPLEVELPARENTIDHERE;
这种方法确实有固定的深度限制。我从自己的数据中知道,它恰好最多跨越五个深度级别。如果深度相当稳定,您可以通过简单地添加更多的左连接来适应一些增长。此外,也不确定查询将如何处理数十万条记录。