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

PHP中使用两个SQL表数据时结果重复的问题解决

问题修复:商品重复显示与积分查询优化

问题根源

你使用了CROSS JOIN,这会生成笛卡尔积——shopitems的每一条记录都会和listings的每一条记录强制配对。如果listings表中有3条用户数据,6个商品就会得到6×3=18条重复结果,这就是重复显示的原因。

修复方案

你只需要当前登录用户的points字段,完全不需要对两张表做全量关联。正确的做法是:

  • 先单独查询当前用户的积分余额
  • 再查询所有商品,用拿到的积分逐个判断购买状态

修改后的代码

<?php
include('../config.php');
try {
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // 第一步:获取当前登录用户的积分(假设用session存储用户ID,listings表有user_id字段)
    // 请根据实际登录逻辑替换$_SESSION['user_id']为正确的用户标识
    $user_id = $_SESSION['user_id'];
    $stmt_balance = $conn->prepare("SELECT points FROM listings WHERE user_id = ?");
    $stmt_balance->execute([$user_id]);
    $user_data = $stmt_balance->fetch(PDO::FETCH_ASSOC);
    $balance = $user_data['points'] ?? 0; // 处理用户无记录的情况,默认0积分

    // 第二步:查询所有商品,无需关联listings表
    $stmt = $conn->prepare("SELECT * FROM shopitems");
    $stmt->execute();
    $stmt->setFetchMode(PDO::FETCH_ASSOC); // 将fetchMode放在循环外,提升效率

    while($row = $stmt->fetch()) {
        $cost = $row['itemcost'];
        $status = $balance < $cost ? 'Not enough points' : 'Purchase';

        echo '
        <div class="col-lg mb-md-0 mb-4">
          <div class="card border rounded shadow-none">
            <div class="card-body">
              <div class="my-3 pt-2 text-center">
                <img src="'.$row['itemimage'].'" alt="Basic Image" height="140">
              </div>
              <h3 class="card-title text-center text-capitalize mb-1">'.$row['itemname'].'</h3>

              <div class="text-center">
                <div class="d-flex justify-content-center">
                  <sup class="h6 pricing-currency mt-3 mb-0 me-1 text-primary">P</sup>
                  <h1 class="display-4 mb-0 text-primary">'.$row['itemcost'].'</h1>
                </div>
              </div>
<br/>

<a href="./protected/webhook-alerts/shop-purchase.php?desc='.$row['itemdesc'].'" method="post" type="submit" class="btn btn-primary d-grid w-100 post">'.$status.'</a>
            </div>
          </div>
        </div>
        ';
    }
} catch(PDOException $e) {
    echo "Error: " . $e->getMessage();
}
?>

关键修改点

  • 移除CROSS JOIN,彻底避免笛卡尔积导致的重复结果
  • 单独查询当前用户积分,避免不必要的全表关联
  • 将setFetchMode移到循环外,减少重复执行的开销
  • 增加积分默认值处理,避免用户无记录时出现报错

补充说明

如果你的listings表没有user_id字段,或者用户登录逻辑不同,请根据实际情况调整查询用户积分的SQL语句,核心原则是只获取当前用户的积分数据,而非全表的积分记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 20:23:17