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

PHP+MySQL关联查询文章分类结果重复,需实现分类名逗号分隔展示

实现方案

你可以从SQL聚合、PHP重组两个方向调整,优先推荐SQL层直接聚合的方案,代码更简洁性能更好。

方案1:SQL层使用GROUP_CONCAT聚合(推荐)

出现重复行的核心原因是JOIN关联后一篇文章对应N条分类关联记录就会返回N行,直接用MySQL内置的GROUP_CONCAT()函数按文章分组,把同文章下的分类名拼接成单个字段即可从根源解决问题。
注意你原代码里取文章标题的字段名写错了:表结构里标题字段是title,不是post_title,直接用会报字段不存在错误。
修改后的SQL语句:

SELECT 
    p.post_id,
    p.title,
    p.date,
    GROUP_CONCAT(c.category_name SEPARATOR ',') AS category_names
FROM tbl_post p
INNER JOIN tbl_post_category pc ON p.post_id = pc.post_id
INNER JOIN tbl_category c ON pc.category_id = c.category_id
GROUP BY p.post_id, p.title, p.date
ORDER BY p.post_id DESC

提示:MySQL默认GROUP_CONCAT单字段最大拼接长度为1024字符,如果单篇文章关联分类较多可能出现内容截断,可在执行查询前先运行SET SESSION group_concat_max_len = 10240;临时调大当前连接的拼接长度上限。
对应调整后的PHP代码:

<?php
$i = 0;
$sql = "SELECT 
    p.post_id,
    p.title,
    p.date,
    GROUP_CONCAT(c.category_name SEPARATOR ',') AS category_names
FROM tbl_post p
INNER JOIN tbl_post_category pc ON p.post_id = pc.post_id
INNER JOIN tbl_category c ON pc.category_id = c.category_id
GROUP BY p.post_id, p.title, p.date
ORDER BY p.post_id DESC";
$statement = $pdo->prepare($sql);
$statement->execute();
$result = $statement->fetchAll(PDO::FETCH_ASSOC);                           
foreach ($result as $row) {
    $i++;
?>
<?php echo $i; ?>
<?php echo $row['title']; ?>
<?php echo $row['category_names']; ?>
<?php } ?>

方案2:PHP层遍历重组数据(无需修改原SQL)

如果不想调整原有查询逻辑,可以保留原SQL语句,拿到查询结果后在PHP层按文章ID分组,收集同文章下的所有分类名后手动拼接,代码如下:

<?php
$i = 0;
$statement = $pdo->prepare("SELECT * FROM tbl_post JOIN tbl_post_category ON tbl_post.post_id = tbl_post_category.post_id INNER JOIN tbl_category ON tbl_post_category.category_id = tbl_category.category_id
ORDER BY tbl_post.post_id DESC");
$statement->execute();
$rawResult = $statement->fetchAll(PDO::FETCH_ASSOC);
// 按文章ID重组数据
$postList = [];
foreach ($rawResult as $item) {
    $postId = $item['post_id'];
    if (!isset($postList[$postId])) {
        $postList[$postId] = [
            'post_id' => $postId,
            'title' => $item['title'],
            'date' => $item['date'],
            'category_list' => []
        ];
    }
    $postList[$postId]['category_list'][] = $item['category_name'];
}
// 遍历输出处理后的数据
foreach ($postList as $row) {
    $i++;
?>
<?php echo $i; ?>
<?php echo $row['title']; ?>
<?php echo implode(',', $row['category_list']); ?>
<?php } ?>

额外优化建议

  • 你提供的建表SQL存在两处语法错误,建议修正:tbl_category建表语句末尾缺少分号,tbl_post_category表中post_id字段定义行末尾多了冗余逗号
  • 三张表目前未设置主键、关联字段索引,数据量上来后JOIN查询性能会明显下降,建议给tbl_post.post_id、tbl_category.category_id设置主键,给tbl_post_category.post_id、tbl_post_category.category_id加普通索引。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:27:24