我有一张桌子People
.我希望显示一个由每个父项组成的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 |
|_______________________________________________________|
Run Code Online (Sandbox Code Playgroud)
预期产量:
________________________________________________
|Jeffrey Williams |
|------------------------------------------------|
| - Carol Williams |
| - Sarah Williams |
|________________________________________________|
|James Donovan |
|------------------------------------------------|
| - Nikolai Donovan |
|________________________________________________|
|Emmit Herring |
|------------------------------------------------|
|________________________________________________|
Run Code Online (Sandbox Code Playgroud)
如何构建包含正确迭代结果集的关联数组?我对正确的SQL和正确的PHP构建最终数组感到困惑.
具体来说,我不确定如何在两个MySQL表之间显示层次关系.据我所知,SQL结果集不是多维的.将SQL查询放在for
循环中对性能来说太糟糕了.所以你会怎么做?
我想我正在寻找MySQL中的邻接列表实现.
如果我可以将所有内容分成两个表,这个问题应该很容易,但不幸的是我必须坚持使用这种非正常的表结构.
Ilm*_*nen 13
有几种方法可以做到:
1.显而易见的是首先获取所有父项的列表,然后在循环中为每个父项的子项运行单独的查询.你说这对于"性能很糟糕",但它确实不应该,假设你的parent
列上有一个索引,而你的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
Run Code Online (Sandbox Code Playgroud)
同样,你真的,真的需要在一个索引parent
列.该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
}
}
Run Code Online (Sandbox Code Playgroud)
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
PS.如果您实际上并不想显示表中的所有父项和子项,而只是表示属于单个族的那些父项和子项,那么您仍应尝试在SQL中进行过滤以避免获取太多记录.
归档时间: |
|
查看次数: |
4798 次 |
最近记录: |