我正在为一个工作项目处理一些分层的数据,并试图找到一种更有效的处理方式,因为我的第一次尝试可能在很多方面都很可怕。 我在这个网站上查看了许多分层数据问题,所以我知道以我的结构几乎不可能在单个查询中获取信息。
我正在查询的表位于 AS/400 上,每个条目存储单个步骤的单个部分,因此,如果我有 PartOne 和三个组件进入其中,则每个条目都有一个条目,例如:
PartOne ComponentOne, PartOne ComponentTwo, PartThree ComponentThree.
请务必注意,如果 ComponentOne 有组件,后续行可能包含:
ComponentOne SubComponentOne, ComponentOne SubComponentTwo.
考虑到这一点,我试图将所有组件放在给定成品零件的树状结构中,基本上得到最终产品中的所有内容。
我无法为此创建一个扁平表,因为我正在尝试做的是动态生成该扁平表。 但是,我确实可以访问成品零件列表。 所以我目前的算法是这样的
- 获取零件编号,当这是创建的零件时,查询组件的表。 获取
- 这些组件并查询每个组件作为创建的部件并获取它们的组件。
- 重复直到查询未返回任何条目。
在本例中,这是 7 个深度查询。 我想知道外面的任何人是否对此有更好的算法是否有意义,而且自从我做递归以来已经有一段时间了,但这至少在创建查询时对于递归来说似乎是合理的。 考虑创建一个递归函数,从每个级别传回查询结果,并将信息存储在数组/表/数据库条目中的某个地方,这是否合理?
你想要 php 中的树结构吗?然后下一个代码示例可能会很有趣。
这将为类别表中的记录构建一个树,从 id -1000 开始作为根元素,仅使用与所需信息深度一样多的查询。
表结构:
TABLE categories (
id INT NOT NULL PRIMARY KEY,
parent_id INT NULL,
name NVARCHAR(40) NOT NULL
)
PHP代码:
class Bom {
public $Id;
public $Name;
public $Components = array();
function __construct( $id, $name ) {
$this->Id = $id;
$this->Name = $name;
}
}
$parentIds = array( -1000 ); // List of id's to lookup
$rootBom = new Bom( -1000, 'Root' );
$bomsById[ -1000 ][] = $rootBom; // For each id there can be multiple instances if we want separate instances of Bom for each time it occurs in the tree
$maxLevel = 0;
while ( count( $parentIds ) > 0
&& $maxLevel++ < 10
&& $result = $mysqli->query( "SELECT * FROM categories WHERE parent_id IN ( " . implode( ", ", $parentIds ) . " ) ORDER BY name" ) )
{
$parentIds = array(); // Clear the lookup list
$newBomsById = array();
while ( $row = $result->fetch_assoc() )
{
$boms = $bomsById[ $row[ 'parent_id' ] ];
if ( $boms )
{
foreach ( $boms as $bomToUpdate )
{
$compontentBom = new Bom( $row[ 'id' ], $row[ 'name' ] );
$bomToUpdate->Components[] = $compontentBom;
$newBomsById[ $compontentBom->Id ][] = $compontentBom;
}
$parentIds[] = $row[ 'id' ]; // Build new list of id's to lookup
}
}
$bomsById = $newBomsById;
}
echo '<!--
' . print_r( $rootBom, true ) . '
-->';