如何用单条PHP MySQL查询展示关注用户及登录用户动态并解决重复问题?
解决登录用户帖子重复显示的问题
首先咱们来拆解下重复出现的原因:你的查询用了LEFT JOIN followers,同时WHERE条件是posts.added_by_user_id = $id OR followers.followed_by = $id。当帖子是你自己发布的时候,第一个条件已经满足;如果followers表里存在你关注自己的记录(也就是followed = $id且followed_by = $id),这条帖子会被OR条件的后半段再次匹配,最终导致同一条帖子返回两次。
下面给你两个实用的解决方案:
方案1:用DISTINCT快速去重
这是最直接的修复方式,在SELECT后加上DISTINCT关键字,强制返回唯一的记录:
$que = $db->prepare("SELECT DISTINCT posts.*, users.*, followers.follow, followers.followed_by FROM posts INNER JOIN users ON users.user_id = posts.added_by_user_id LEFT JOIN followers ON followers.follow = posts.added_by_user_id WHERE (posts.added_by_user_id = $id OR followers.followed_by = $id) ORDER BY post_id DESC"); $que->execute(); $posts = $que->fetchAll();
不过这个方法属于“治标”,如果后续数据量变大,可能会影响查询性能,更推荐下面的优化方案。
方案2:重构查询逻辑(更优解)
先把需要展示的用户ID集合整理出来(你自己的ID + 已关注的用户ID),再查询这些用户的帖子,从根源上避免重复:
// 用参数绑定避免SQL注入,更安全 $que = $db->prepare(" SELECT posts.*, users.* FROM posts INNER JOIN users ON users.user_id = posts.added_by_user_id WHERE posts.added_by_user_id IN ( SELECT ? AS user_id UNION SELECT followed FROM followers WHERE followed_by = ? ) ORDER BY post_id DESC "); $que->execute([$id, $id]); $posts = $que->fetchAll();
这个查询的逻辑很清晰:
- 用
UNION把你自己的ID和关注的用户ID合并成一个列表 - 只查询这个列表里用户发布的帖子
- 每个帖子只会被匹配一次,自然不会出现重复
另外提醒下:你原来的查询直接把$id拼进SQL里,存在SQL注入风险,上面的方案用了参数绑定(?占位符),这是更规范的安全写法哦。
内容的提问来源于stack exchange,提问作者Azixy_codes
相关产品推荐
相关产品推荐

