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

多对多关系下查询特定用户是否点赞全部帖子的SQL问题

解决帖子列表标注特定用户点赞状态的问题

嗨,我来帮你搞定这个问题!你遇到的核心困扰其实是过滤条件的位置放错了——把用户的点赞过滤条件放到WHERE里会误删数据,而放到LEFT JOIN的ON子句里,就能完美保留所有帖子,同时准确标记目标用户的点赞状态。

方案一:用LEFT JOIN + ON子句过滤目标用户

这是最直接的写法,关键是把likes.user_id = 目标用户ID放到关联条件里,而不是事后用WHERE过滤:

SELECT 
    p.*,
    -- 用CASE判断是否点赞,1表示已点赞,0表示未点赞
    CASE WHEN l.user_id IS NOT NULL THEN 1 ELSE 0 END AS is_liked_by_target_user
FROM posts p
LEFT JOIN likes l 
    ON p.post_id = l.post_id 
    AND l.user_id = 1; -- 这里指定你要查询的用户ID,比如1

原理说明:

  • LEFT JOIN会强制保留posts表的所有行,不管likes表有没有匹配的记录。
  • 把l.user_id = 1放到ON子句里,意味着只关联当前目标用户的点赞记录,其他用户的点赞不会被关联进来,自然就不会出现帖子重复的情况。
  • 如果目标用户没点赞该帖子,l.user_id会是NULL,通过CASE就能准确标记状态。

方案二:用EXISTS子查询(性能更优)

如果不需要获取点赞的其他细节(比如点赞时间),用EXISTS子查询会更简洁,而且性能通常更好,因为它只要找到匹配的点赞记录就停止查询,不会产生冗余数据:

SELECT 
    p.*,
    -- EXISTS返回布尔值,直接转成1/0表示点赞状态
    EXISTS (
        SELECT 1 
        FROM likes l 
        WHERE l.post_id = p.post_id 
        AND l.user_id = 1
    ) AS is_liked_by_target_user
FROM posts p;

为什么之前的写法会出问题?

你提到的WHERE likes.user_id = 1 AND likes.user_id IS NULL(推测应该是OR)之所以不行,是因为:
当帖子被其他用户点赞但目标用户没点时,likes.user_id会是其他用户的ID,既不是1也不是NULL,WHERE条件会把这些行直接过滤掉,导致你丢失了这些帖子。而把条件放到ON子句里,只会影响关联结果,不会删除posts表的原始行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:37:47