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

PHP/SQL关联两张表并获取课程平均评分的实现问题

问题:展示2017年课程及对应平均评分时重复显示相同评分

我来帮你解决这个问题!你需要列出2017年开设的所有课程,并在每门课旁显示对应的平均反馈评分,但当前代码里每一行都重复显示相同的评分,咱们一步步来排查修复:

先明确你的数据表结构

courses表

course_idcourse_name
1Public speaking
2Social media skills

feedback表

course_idoverall_rating
13
15
14
14
23
23
24

问题根源分析

你的代码有两个核心问题:

  1. SQL硬编码错误:获取平均评分的语句SELECT AVG(overall_rating) FROM feedback WHERE courseid='courseid'里,'courseid'是字符串字面量,不是循环中的变量,所以每次查询都在找courseid等于字符串"courseid"的记录(显然不存在或只会返回固定ID的评分),导致所有行显示相同结果。
  2. 低效的数据库交互:在循环中每次单独查询一次平均评分,会增加数据库的负载,性能较差。

解决方案

方案1:修复原循环逻辑(基础修复)

把SQL中的courseid替换为当前循环的课程ID,同时用参数绑定避免SQL注入:

<table cellspacing="0" border="1" cellpadding="5">
    <tr style="font-size:20px; font-weight:bold; text-align:center;">
        <td colspan="3">2017</td>
    </tr>
    <tr style="font-weight:bold;">
        <td style="background-color:#AED6F1;">Course ID</td>
        <td style="background-color:#AED6F1;">Course title</td>
        <td style="background-color:#AED6F1;">Average rating</td>
    </tr>
    <?php
    // 获取2017年所有课程
    $yearscourses = "SELECT courseid, coursetitle FROM courses WHERE coursedate1 BETWEEN '2017-01-01' AND '2017-12-31'";
    $yearsresult = mysqli_query($connect, $yearscourses);

    if (mysqli_num_rows($yearsresult) > 0) {
        while ($row = mysqli_fetch_array($yearsresult, MYSQLI_ASSOC)) {
            $courseId = $row['courseid'];
            // 使用参数绑定查询当前课程的平均评分,避免SQL注入
            $avgrating = "SELECT AVG(overall_rating) AS avg_rating FROM feedback WHERE courseid = ?";
            $stmt = mysqli_prepare($connect, $avgrating);
            mysqli_stmt_bind_param($stmt, "i", $courseId);
            mysqli_stmt_execute($stmt);
            $avgresult = mysqli_stmt_get_result($stmt);
            $row2 = mysqli_fetch_assoc($avgresult);
            // 处理无反馈的情况,显示N/A或0
            $avgRating = $row2['avg_rating'] ?? "N/A";
            // 格式化评分,保留1位小数
            $avgRating = is_numeric($avgRating) ? number_format($avgRating, 1) : $avgRating;

            echo "<tr>
                    <td>" . htmlspecialchars($row['courseid']) . "</td>
                    <td>" . htmlspecialchars($row['coursetitle']) . "</td>
                    <td>" . $avgRating . "</td>
                  </tr>\n";
            mysqli_stmt_close($stmt);
        }
    } else {
        echo "<tr><td colspan='3'>No courses found in 2017</td></tr>";
    }
    ?>
</table>

方案2:使用单SQL查询(推荐,更高效)

通过LEFT JOIN关联两张表,一次性获取所有课程和对应的平均评分,减少数据库交互:

<table cellspacing="0" border="1" cellpadding="5">
    <tr style="font-size:20px; font-weight:bold; text-align:center;">
        <td colspan="3">2017</td>
    </tr>
    <tr style="font-weight:bold;">
        <td style="background-color:#AED6F1;">Course ID</td>
        <td style="background-color:#AED6F1;">Course title</td>
        <td style="background-color:#AED6F1;">Average rating</td>
    </tr>
    <?php
    // 一次性查询2017年课程及对应平均评分
    $query = "
        SELECT c.courseid, c.coursetitle, AVG(f.overall_rating) AS avg_rating
        FROM courses c
        LEFT JOIN feedback f ON c.courseid = f.courseid
        WHERE c.coursedate1 BETWEEN '2017-01-01' AND '2017-12-31'
        GROUP BY c.courseid, c.coursetitle
    ";
    $result = mysqli_query($connect, $query);

    if (mysqli_num_rows($result) > 0) {
        while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
            $avgRating = $row['avg_rating'] ?? "N/A";
            $avgRating = is_numeric($avgRating) ? number_format($avgRating, 1) : $avgRating;

            echo "<tr>
                    <td>" . htmlspecialchars($row['courseid']) . "</td>
                    <td>" . htmlspecialchars($row['coursetitle']) . "</td>
                    <td>" . $avgRating . "</td>
                  </tr>\n";
        }
    } else {
        echo "<tr><td colspan='3'>No courses found in 2017</td></tr>";
    }
    ?>
</table>

额外提示

  • 用htmlspecialchars()转义输出内容,防止XSS攻击。
  • LEFT JOIN确保即使课程没有任何反馈,也会被显示出来;如果用INNER JOIN则只会显示有反馈的课程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:44:07