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

MySQL中SUM用DISTINCT无效,关联查询统计数据异常求助

解决SQL多表关联导致评论数翻倍的问题

这个问题我太熟悉了——你遇到的是SQL多表关联产生笛卡尔积的经典坑!

问题原因分析

当你同时用LEFT JOIN把likes和comentarios两张表关联到posts时,数据库会生成两张表的笛卡尔积:每一条点赞记录都会和该帖子的所有评论记录做组合。比如你有2条点赞、3条评论,关联后会生成2×3=6条记录。你的点赞数用了COUNT(DISTINCT likes.user),所以能得到正确的2;但评论数用SUM(CASE ...)时,每条评论会被重复计算(次数等于点赞数),所以最终得到6,正好是你看到的结果。

之前你尝试在SUM后加DISTINCT没用,是因为SUM(DISTINCT ...)会对CASE返回的1/0去重,结果要么是1要么是0,完全不符合统计需求。

两种可行的解决方案

方案1:子查询分别统计(推荐,性能更优)

先分别统计每个帖子的点赞数和有效评论数,再关联到主表,从根源避免笛卡尔积:

SELECT 
    p.id,
    COALESCE(l.likes_count, 0) AS likes_count,
    COALESCE(c.comentarios_count, 0) AS comentarios_count
FROM posts p
LEFT JOIN (
    -- 先统计每个帖子的点赞数
    SELECT post, COUNT(DISTINCT user) AS likes_count
    FROM likes
    GROUP BY post
) l ON l.post = p.id
LEFT JOIN (
    -- 先统计每个帖子的未删除评论数
    SELECT foto, SUM(CASE WHEN `delete` = 0 THEN 1 ELSE 0 END) AS comentarios_count
    FROM comentarios
    GROUP BY foto
) c ON c.foto = p.id;

这里用COALESCE是为了处理那些没有点赞或评论的帖子,确保返回0而不是NULL。

方案2:用COUNT(DISTINCT)统计评论ID

如果不想改结构,也可以对评论的唯一ID去重统计,抵消笛卡尔积的影响:

SELECT 
    p.id,
    COUNT(DISTINCT likes.user) AS likes_count,
    COUNT(DISTINCT CASE WHEN comentarios.`delete` = 0 THEN comentarios.id END) AS comentarios_count
FROM posts p
LEFT JOIN likes ON likes.post = p.id
LEFT JOIN comentarios ON comentarios.foto = p.id
GROUP BY p.id;

注意:这种方法虽然简单,但性能不如方案1,因为关联后还是会生成大量重复记录,再通过去重统计,数据量大时会拖慢查询速度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:12:41