You need to enable JavaScript to run this app. PHP使用单次MySQL查询提取两级数据并按顶层分类分组展示的实现问题
优惠活动
大模型
产品
解决方案
定价
更多

PHP使用单次MySQL查询提取两级数据并按顶层分类分组展示的实现问题

实现方案

你可以通过先分组再输出,或者循环时判断父分类切换的方式实现需求,两种方案都只需要单次SQL查询。

首先调整SQL的排序规则,保证同一父分类下的所有记录(父分类本身+子项)连续排列,且父分类排在子项前面:

SELECT * FROM menu WHERE org = ? ORDER BY COALESCE(NULLIF(parent, ''), mid) ASC, parent IS NOT NULL ASC

方案1:先组装分组数组再输出(推荐,可读性更高)

先遍历查询结果把父子项按分类组装,再遍历分组输出HTML:

<?php
$org = "1";
$stmt = mysqli_prepare($db, "SELECT * FROM menu WHERE org = ? ORDER BY COALESCE(NULLIF(parent, ''), mid) ASC, parent IS NOT NULL ASC");
$stmt->bind_param("s", $org);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);

// 组装分组数据
$groupedData = [];
while ($row = mysqli_fetch_assoc($result)) {
    if (empty($row['parent'])) {
        // 父分类记录
        $groupedData[$row['mid']]['category'] = $row;
    } else {
        // 子项记录,归属到对应父分类
        $groupedData[$row['parent']]['items'][] = $row;
    }
}

// 输出HTML
foreach ($groupedData as $group) {
?>
<div class="category"><?php echo htmlspecialchars($group['category']['item']); ?><br>
<?php foreach ($group['items'] as $item) { ?>
    <div class="item"><?php echo htmlspecialchars($item['item']); ?></div>
<?php } ?>
</div>
<?php } ?>

方案2:单次循环直接输出(适合大数据量场景,节省内存)

通过变量记录当前父分类ID,遇到新父分类时关闭上一个分类容器再打开新容器:

<?php
$org = "1";
$stmt = mysqli_prepare($db, "SELECT * FROM menu WHERE org = ? ORDER BY COALESCE(NULLIF(parent, ''), mid) ASC, parent IS NOT NULL ASC");
$stmt->bind_param("s", $org);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);

$currentCatId = null;
while ($row = mysqli_fetch_assoc($result)) {
    if (empty($row['parent'])) {
        // 遇到新的父分类,先关闭上一个分类的div
        if ($currentCatId !== null) {
            echo '</div>';
        }
        // 输出新分类头部
        echo '<div class="category">' . htmlspecialchars($row['item']) . '<br>';
        $currentCatId = $row['mid'];
    } else {
        // 输出子项
        echo '<div class="item">' . htmlspecialchars($row['item']) . '</div>';
    }
}
// 循环结束后关闭最后一个分类容器
if ($currentCatId !== null) {
    echo '</div>';
}
?>

注意事项

  • 输出内容统一加htmlspecialchars转义,避免XSS注入风险
  • 如果需要展示价格,直接在子项输出位置加echo htmlspecialchars($item['price'])即可
  • 方案1后续扩展更方便,比如添加分类判断、子项为空时的提示等逻辑成本更低

内容的提问来源于stack exchange,提问作者stefan999

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 23:06:03