如何在 MySQL 中使用 PHP 递归地从子元素为空的祖先中获取值
Posted
技术标签:
【中文标题】如何在 MySQL 中使用 PHP 递归地从子元素为空的祖先中获取值【英文标题】:How to Grab value from ancestors in MySQL where child element is null recursively using PHP 【发布时间】:2013-10-15 19:58:37 【问题描述】:我不确定这是否完全符合我的措辞,但我们开始吧: 我试图弄清楚如何在 php 中创建一个递归循环,该循环基本上检查子列是否为 null - 如果该子元素列具有 null 值,则它使用父 id 递归地遍历其祖先,直到找到具有该列的值,然后将该父值放入原始子列中。由于我刚开始使用 php,但我对数据库和 mysql 有深入的了解,因此我对此感到非常困惑。任何帮助和代码示例都会很棒。
【问题讨论】:
只是为了确定:您是在描述一个包含 ParentID、ChildID 和 TheThingIWant 列的表吗?并且您要选择 TheThingIWant,或者如果 TheThingIWant 为 null,则从最近的祖先中选择 TheThingIWant? 是的,这基本上就是我想要实现的目标。对不起,如果措辞有点混乱。 【参考方案1】:关于使用邻接列表模型存储分层数据的警告:它以易于创建和更新表为代价换取了重新获取数据的效率低下。我个人在我的项目中使用了Closure Tables,因为即使弄清楚如何在那里获取数据以及如何更新它们是很疯狂的,但在再次获取数据方面效率要高得多。如果您有 Closure Tables,您可以使用一个查询来获取节点的所有具有信息的父节点的列表,并使用 ORDER BY Distance LIMIT 1 来获取您想要的父节点作为您的答案。使用Nested Sets 也是一种选择,尽管我对它们知之甚少。在继续之前,您应该研究这些并考虑您的选择。
这是您现在拥有的邻接列表:
$target = 4; //whatever ID
$db = new mysqli(HOST, USERNAME, PASSWORD, DATABASE);
if($db->connect_errno > 0)
die('Unable to connect to database [' . $db->connect_error . ']');
$statement = $db->prepare("SELECT ParentID, Audience FROM things WHERE ChildID = ?");
$audience = NULL;
$ChildID = $target; // starts as same value
while(!isset($audience) || !isset($ChildID)) //This assumes that the top ParentID is null; you might have to adjust it
$statement->bind_param('i', $ChildID);
$statement->execute();
$result = $statement->get_result();
while($row = $result->fetch_assoc())
if(!isset($row['Audience']) && !isset($audience))
$ChildID = isset($row['ParentID'])?$row['ParentID']:NULL;
else
$audience = $row['Audience'];
$result->free();
if(isset($audience))
if($target == $ChildID) //it was found on that first try
echo $audience.' was found for '.$target;
else
$statement = $db->prepare("UPDATE things SET Audience = ? WHERE ChildID = ?");
$statement->bind_param('si', $audience, $target);
$statement->execute();
echo $audience.' was set for '.$target;
else
echo 'No audience was found or set for '.$target;
$db->close();
请注意,bind_param 的第一个参数关心您的绑定对象是什么类型(字符串、整数、小数、blob)。你可能需要查一下。
【讨论】:
【参考方案2】:请提供示例表/字段。我们无法判断您是指一张桌子还是几张桌子。
您的 php 代码可能看起来像这样(查询内容是伪代码)
function updateChild($ChildID,$ParentID=-1)
//use mysqlquery or whatever
if($ParentID==-1)
select field_value,parent_id from mytable where rowid=$ChildID;
else
select field_value,parent_id from mytable where parentid=$ParentID;
$candidate_value=$row['field_value'];
$fallback_parent=$row['parent_id']
if ( is_null($candidate_value))
updateChild($ChildID, $fallback_parent)
else
update mytable set field_value=$candidate_value where $ChildID=$ChildID
我们的想法是首先获取当前字段值和 parentID,以防万一。如果结果为空,则再次调用相同的函数,传入子项或 rowid 以及下一个要检查的父项。如果父母证明是好的,它会使用一直传递的子值进行更新。请注意,如果上面的代码在第一次尝试时确实有值,则将使用“自身”更新子值,因此应该通过检查 parentid 是否为 -1 来解决这个问题。
【讨论】:
这将是我们正在浏览的一张表。假设您有一个名为“audience”的列,它可以为空,我们基本上试图用来自父级或祖先的值填充此列,但我们只想为子级填充“audience”列,如果父母或祖先对“观众”有实际价值——这就是我必须有递归代码的原因。 *如果子“audience”列确实有值,我们也不想填充它以上是关于如何在 MySQL 中使用 PHP 递归地从子元素为空的祖先中获取值的主要内容,如果未能解决你的问题,请参考以下文章
PHP - 当给定子键名时,递归地将每个数组元素的键设置为子元素的值
如何使用 jQuery 从子元素中获取数据以在 xml api 中查找其他子元素?