You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于5张指定数据表获取分类、子分类及文章并输出嵌套ul HTML

解决方案

一、SQL查询调整

你原来的SQL仅获取了父ID为99的一级分类,没有覆盖一级分类下的多层子分类,我们用递归CTE(支持MySQL 8.0+、MariaDB 10.2+及以上版本)拉取完整的分类树,调整后语句如下:

WITH RECURSIVE category_tree AS (
    -- 先获取根节点下的一级分类
    SELECT 
        ac.articlecat_id,
        ac.parent_id,
        acd.articlecat_name
    FROM table_article_categories AS ac
    INNER JOIN table_article_categories_description AS acd
        ON ac.articlecat_id = acd.articlecat_id
        AND acd.language_id = 1
    WHERE 
        ac.parent_id = 99
        AND ac.articlecat_status = 1
        AND ac.articlecat_id != 77
    UNION ALL
    -- 递归获取所有子分类
    SELECT 
        ac_child.articlecat_id,
        ac_child.parent_id,
        acd_child.articlecat_name
    FROM table_article_categories AS ac_child
    INNER JOIN category_tree AS ct ON ac_child.parent_id = ct.articlecat_id
    INNER JOIN table_article_categories_description AS acd_child
        ON ac_child.articlecat_id = acd_child.articlecat_id
        AND acd_child.language_id = 1
    WHERE 
        ac_child.articlecat_status = 1
        AND ac_child.articlecat_id != 77
)
-- 关联获取分类下的文章
SELECT
    ct.parent_id,
    ct.articlecat_id,
    ct.articlecat_name,
    a.articles_id,
    ad.articles_heading_title AS article_name
FROM category_tree AS ct
LEFT JOIN table_article_to_article_categories AS atac
    ON atac.articlecat_id = ct.articlecat_id
LEFT JOIN table_articles AS a
    ON a.articles_id = atac.articles_id
    AND a.articles_status = 1
LEFT JOIN table_articles_description AS ad
    ON ad.articles_id = a.articles_id
    AND ad.language_id = 1
ORDER BY
    ct.articlecat_name ASC,
    article_name ASC

如果用的是不支持递归CTE的低版本数据库,可以先查询所有符合状态的分类,在代码层面组装分类树,不需要在SQL层做递归处理。

二、后续数据处理&HTML生成逻辑

核心思路是先把SQL返回的扁平数据转换成嵌套的树形结构,再递归生成嵌套<ul>标签,通用处理步骤如下:

  1. 结构化数据
    遍历SQL查询结果,把数据整理成两层映射:
  • 分类映射:键为分类ID,值为分类详情(名称、父ID、子分类列表、文章列表)
  • 父分类映射:键为父分类ID,值为该父分类下的所有子分类ID列表
    遍历过程中遇到文章ID非空的条目,就把文章标题加入对应分类的文章列表里,注意分类信息要去重,不要重复存储同一分类的信息。
  1. 递归生成HTML
    写一个递归函数,输入为父分类ID,输出为该分类下的嵌套<ul>字符串,此处以PHP为例,其他语言逻辑一致:
function build_category_ul($parent_id, $category_map, $parent_child_map) {
    $html = '<ul>';
    // 遍历当前父分类下的所有子分类
    foreach ($parent_child_map[$parent_id] ?? [] as $cat_id) {
        $cat = $category_map[$cat_id];
        $html .= '<li>' . htmlspecialchars($cat['articlecat_name']);
        // 先添加子分类的嵌套列表
        if (isset($parent_child_map[$cat_id])) {
            $html .= build_category_ul($cat_id, $category_map, $parent_child_map);
        }
        // 再添加当前分类下的文章列表
        if (!empty($cat['articles'])) {
            $html .= '<ul>';
            foreach ($cat['articles'] as $article) {
                $html .= '<li>' . htmlspecialchars($article) . '</li>';
            }
            $html .= '</ul>';
        }
        $html .= '</li>';
    }
    $html .= '</ul>';
    return $html;
}

// 调用方法,根分类的父ID是99
echo build_category_ul(99, $category_map, $parent_child_map);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 13:54:08