MySQL多表关联问题:如何引入member_ratings表获取会员评分
解决MySQL三张表关联获取评分的问题
首先,你的需求是找出所有给当前用户转过积分的会员,并显示当前用户对他们的评分(未评分则显示"pending")。核心是用LEFT JOIN关联member_ratings表,因为可能存在没有评分记录的情况,同时用COALESCE函数处理空值。
改写后的SQL语句
$sql = 'SELECT m.id AS point_id, c1.id AS id_from, c1.name AS name_from, c2.id AS id_to, c2.name AS name_to, COALESCE(r.rating, "pending") AS rating FROM member_points AS m JOIN members AS c1 ON m.id_from = c1.id JOIN members AS c2 ON m.id_to = c2.id LEFT JOIN member_ratings AS r ON r.id_from = m.id_to AND r.id_to = m.id_from WHERE m.id_to = ' . $_SESSION["userid"] . ' GROUP BY c1.id'; -- 用id分组比name更可靠,避免同名会员冲突
关键说明
LEFT JOIN 关联评分表:
- 关联条件
r.id_from = m.id_to表示评分的发起者是当前用户(因为m.id_to是当前用户ID); r.id_to = m.id_from表示评分的接收者是给当前用户转积分的人(也就是member_points里的转账发起者)。- 用LEFT JOIN可以保留所有给当前用户转积分的记录,哪怕没有对应的评分。
- 关联条件
COALESCE处理空值:
- 当
member_ratings中没有匹配记录时,r.rating会是NULL,COALESCE会将其替换为"pending",正好符合你的需求。
- 当
GROUP BY优化:
- 原SQL用
GROUP BY name_from存在风险,如果有同名会员会导致数据合并错误,改用c1.id(会员唯一ID)分组更准确。
- 原SQL用
重要安全提示
直接拼接$_SESSION["userid"]到SQL语句中存在SQL注入风险,建议使用预处理语句(PDO或mysqli)来避免这个问题,示例如下(以PDO为例):
$userId = $_SESSION["userid"]; $sql = 'SELECT m.id AS point_id, c1.id AS id_from, c1.name AS name_from, c2.id AS id_to, c2.name AS name_to, COALESCE(r.rating, "pending") AS rating FROM member_points AS m JOIN members AS c1 ON m.id_from = c1.id JOIN members AS c2 ON m.id_to = c2.id LEFT JOIN member_ratings AS r ON r.id_from = m.id_to AND r.id_to = m.id_from WHERE m.id_to = ? GROUP BY c1.id'; $stmt = $pdo->prepare($sql); $stmt->execute([$userId]); $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
这样既实现了你的功能,又保证了代码的安全性。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

