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

如何从MySQL的两个关联表生成按系列分组的游戏列表

如何从MySQL的两个关联表生成按系列分组的游戏列表

看起来你已经离目标很近啦!你的需求是在网站上展示按系列分组的游戏列表,每个系列名称只在第一次出现时显示,下面依次列出对应游戏。咱们来一步步解决你遇到的问题,先分析下之前尝试的两种方式的问题,再给出可行的解决方案。

先理清楚你之前的问题

  1. JOIN查询的问题:确实会返回每条游戏对应一条带系列名的记录,所以前端会重复显示系列名,但这个可以通过PHP的逻辑判断来控制只在系列变化时显示名称。
  2. 嵌套查询的问题:你说只显示第一个系列,大概率是代码里的小错误——比如你输出系列名时用了$row['series'],但series表的字段是series_name,不是series,这会导致输出空值,甚至可能破坏HTML结构,让后面的系列无法正常显示。

方案一:用JOIN查询+PHP逻辑控制(推荐,效率更高)

这种方式只需要一次SQL查询,然后在PHP循环里判断当前系列和上一个是否相同,相同就不显示系列名,不同才显示,完全符合你的需求。

优化后的SQL语句

SELECT s.series_name, g.game_name 
FROM series s 
JOIN games g ON s.series_name = g.series 
ORDER BY s.series_name, g.game_name;

这里用了表别名让语句更简洁,同时排序确保同系列的游戏排在一起,避免乱序。

对应PHP+HTML代码

<?php
// 初始化变量,记录上一个显示的系列名
$last_series = '';
// 执行查询
$sql = "SELECT s.series_name, g.game_name FROM series s JOIN games g ON s.series_name = g.series ORDER BY s.series_name, g.game_name";
$result = $conn->query($sql);

// 先输出表格结构
echo '<table class="s-table">
        <thead>
            <tr>
                <th>Series</th>
                <th>Games</th>
            </tr>
        </thead>
        <tbody>';

if ($result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
        $current_series = $row['series_name'];
        $game_name = $row['game_name'];
        
        // 只有当前系列和上一个不同时,才显示系列名
        $series_display = ($current_series !== $last_series) ? $current_series : '';
        
        // 输出表格行,用htmlspecialchars防止XSS攻击
        echo '<tr>
                <td>' . htmlspecialchars($series_display) . '</td>
                <td>' . htmlspecialchars($game_name) . '</td>
              </tr>';
        
        // 更新上一个系列名,方便下一次判断
        $last_series = $current_series;
    }
} else {
    echo '<tr><td colspan="2">没有找到任何数据</td></tr>';
}

echo '</tbody></table>';
?>

方案二:修复嵌套查询的代码

如果你更倾向于用嵌套查询的方式(每个系列单独查对应游戏),那我们来修复之前的代码问题,同时优化安全性。

修复后的PHP代码

<?php
// 查询所有系列,按名称排序
$sql_series = "SELECT series_name FROM series ORDER BY series_name";
$result_series = $conn->query($sql_series);

// 输出表格结构
echo '<table class="s-table">
        <thead>
            <tr>
                <th>Series</th>
                <th>Games</th>
            </tr>
        </thead>
        <tbody>';

if ($result_series->num_rows > 0) {
    while($row_series = $result_series->fetch_assoc()) {
        $current_series = $row_series['series_name'];
        $game_index = 0;
        
        // 用预处理语句查询当前系列的游戏,避免SQL注入
        $sql_games = "SELECT game_name FROM games WHERE series = ? ORDER BY game_name";
        $stmt = $conn->prepare($sql_games);
        $stmt->bind_param("s", $current_series);
        $stmt->execute();
        $result_games = $stmt->get_result();
        
        while($row_game = $result_games->fetch_assoc()) {
            // 只有该系列的第一个游戏行显示系列名
            $series_display = ($game_index === 0) ? $current_series : '';
            
            echo '<tr>
                    <td>' . htmlspecialchars($series_display) . '</td>
                    <td>' . htmlspecialchars($row_game['game_name']) . '</td>
                  </tr>';
            
            $game_index++;
        }
        
        // 每个系列之间加空行,和你想要的示例一致
        echo '<tr><td></td><td></td></tr>';
    }
} else {
    echo '<tr><td colspan="2">没有找到任何系列</td></tr>';
}

echo '</tbody></table>';
?>

这里用了预处理语句来避免SQL注入风险,同时修复了字段名的错误,还控制了系列名只在每个系列的第一个游戏行显示,完全匹配你给出的示例效果。


小提示:添加错误排查

如果你以后遇到类似只显示部分数据的问题,可以在代码里加错误处理,快速定位问题,比如:

if (!$result_series) {
    die("系列查询失败: " . $conn->error);
}

备注:内容来源于stack exchange,提问作者DB_Arcanum

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 09:53:03