我有一张桌子.我想显示一个由每个父母组成的
HTML表,其中所有的孩子都直接在他们的下面.
_________ |People |_____________________________________________ |-------------------------------------------------------| | id | parent | firstname | lastname | |-------------------------------------------------------| | 1 0 James Donovan | | 2 0 Jeffrey Williams | | 3 0 Emmit Herring | | 4 2 Carol Williams | | 5 2 Sarah Williams | | 6 1 Nikolai Donovan | |_______________________________________________________|
预期产量:
________________________________________________ |Jeffrey Williams | |------------------------------------------------| | - Carol Williams | | - Sarah Williams | |________________________________________________| |James Donovan | |------------------------------------------------| | - Nikolai Donovan | |________________________________________________| |Emmit Herring | |------------------------------------------------| |________________________________________________|
如何构建一个包含正确结果集的关联数组来迭代?我对正确的sql和正确的PHP构建最终的数组感到困惑.
具体来说,我不确定如何显示两个MysqL表之间的层次关系.据我所知,sql结果集不是多维的.在for循环中放置SQL查询对于性能来说是可怕的.所以你会怎么做?
我想我正在寻找MysqL中的邻接列表实现.
这个问题应该很容易,如果我可以把所有东西分成两个表,但不幸的是我必须坚持这个不正常的表结构.
有几种方法可以做到:
明显的一个是首先获取所有父母的列表,然后在循环中为每个父项的子项运行单独的查询.你说这是“可怕的性能”,但实际上不应该是,假设你有一个父列上的索引,并且你的MysqL服务器不在地球的另一边.
2.如果你真的想这样做是在一个单一的查询,你可以使用一个LEFT JOIN在桌面上反对自己:
SELECT p.id AS parent_id,p.firstname AS parent_firstname,p.lastname AS parent_lastname,c.id AS child_id,c.firstname AS child_firstname,c.lastname AS child_lastname FROM People AS p LEFT JOIN People AS c ON c.parent = p.id WHERE p.parent = 0 ORDER BY p.id
再次,你真的,真的需要父列上的索引. ORDER BY子句是为了确保每个父项的子节点一起排序;你可以改变它.像p.lastname,p.firstname,p.id,c.lastname,c.firstname,c.id,如果你想按照字母顺序排列的名称.在PHP中,您需要循环结果并在父ID更改时打印一个新标题(并记住处理child_ *列为NULL的情况),如下所示:
$res = MysqL_query( $sql ); $last_parent_id = 0; while ( $row = MysqL_fetch_object( $res ) ) { if ( $row->parent_id != $last_parent_id ) { // print parent header $last_parent_id = $row->parent_id; } if ( $row->child_id ) { // print child row } }
3.第三个选项是使用简单的SELECT * FROM People查询获取所有行,并在PHP中构建树:
$res = MysqL_query( "SELECT * FROM People" ); // add WHERE clauses if needed $names = array(); $parents = array(); $children = array(); while ( $row = MysqL_fetch_object( $res ) ) { $names[ $row->id ] = array( $row->firstname,$row->lastname ); if ( $row->parent == 0 ) { $parents[] = $row->id; } else { if ( !array_key_exists( $row->parent,$children ) ) $children[ $row->parent ] = array(); $children[ $row->parent ][] = $row->id; } } foreach ( $parents as $parent_id ) { // print parent header if ( array_key_exists( $parent_id,$children ) ) { foreach ( $children[ $parent_id ] as $child_id ) { // print child row } } }
PS.如果你真的不想在表中显示所有的父母和孩子,而只是说,那些属于一个家庭的人,那么你还是应该尝试在sql中进行过滤,以避免获取太多的记录.