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

多表关联统计异常:Profiles/Questions/Votes关联结果不符合预期

数据表结构

1. Profiles表

idcreated_atfull_nameinvited_byinvite_countis_adminavatar_urlemail
9e4d5874-1482-41e2-a481-d29ce38b5b672022-11-25 15:53:51.642357+00管理员用户trueadmin@email.com
0f0cf390-5952-4fd6-a436-1d384a2c61b72022-11-25 15:53:51.642357+00测试用户2falsetest@email.com

2. Questions表

idcreated_atquestionowner_idgroup_id
d792c1b6-5578-4771-9192-08aeee3894c32022-11-25 17:11:54.031778+0053w59e4d5874-1482-41e2-a481-d29ce38b5b6700000000-0000-0000-0000-000000000000
3892d4ed-7ab0-4006-b983-ad7eaf0094d52022-11-25 17:17:45.133241+00测试9e4d5874-1482-41e2-a481-d29ce38b5b672d76bc68-3f1b-4801-8d8d-65c3986ee7c0
ab3a0783-1fbe-4d8d-ac56-ce2bd01ff04a2022-11-25 18:03:56.078212+00测试0f0cf390-5952-4fd6-a436-1d384a2c61b700000000-0000-0000-0000-000000000000
0c2a25ad-53d7-499a-8a6d-9b2ed5fde9672022-11-25 18:11:50.776553+00www0f0cf390-5952-4fd6-a436-1d384a2c61b72d76bc68-3f1b-4801-8d8d-65c3986ee7c0

3. Votes表

user_idquestion_idcreated_atansweroption_order
0f0cf390-5952-4fd6-a436-1d384a2c61b73892d4ed-7ab0-4006-b983-ad7eaf0094d52022-11-25 18:01:24.149577+001
0f0cf390-5952-4fd6-a436-1d384a2c61b7d792c1b6-5578-4771-9192-08aeee3894c32022-11-25 18:01:29.606896+002

需求

需要构建如下结构的汇总表:

idcreated_atfull_nameavatar_urlquestions_publishedvotes_cast

错误的SQL语句

SELECT profiles.id,
    profiles.created_at,
    profiles.full_name,
    profiles.avatar_url,
    count(questions.owner_id) AS questions_published,
    count(votes.user_id) AS votes_cast
  FROM public.profiles
  LEFT JOIN public.questions
  ON profiles.id = questions.owner_id
  LEFT JOIN votes
  ON profiles.id = votes.user_id
  GROUP BY profiles.id;

错误执行结果

idcreated_atfull_nameavatar_urlquestions_publishedvotes_cast
0f0cf390-5952-4fd6-a436-1d384a2c61b72022-11-25 15:53:51.642357+00测试用户44
9e4d5874-1482-41e2-a481-d29ce38b5b672022-11-25 15:53:51.642357+00管理员用户20

预期结果

idcreated_atfull_nameavatar_urlquestions_publishedvotes_cast
0f0cf390-5952-4fd6-a436-1d384a2c61b72022-11-25 15:53:51.642357+00测试用户20
9e4d5874-1482-41e2-a481-d29ce38b5b672022-11-25 15:53:51.642357+00管理员用户22

问题分析

原SQL存在两个核心问题:

  1. 笛卡尔积导致计数失真:直接关联三张表时,若一个用户有N个问题、同时存在M条投票记录,会生成N*M条组合记录,最终count统计的是组合行数而非实际数量。比如测试用户有2个问题+2条投票,关联后生成4条记录,导致计数翻倍。
  2. 投票统计逻辑错误:原SQL用profiles.id = votes.user_id统计用户投出的票数,但需求是统计用户发布的问题收到的票数,正确关联条件应为questions.id = votes.question_id。

修正后的SQL语句

方式一:用DISTINCT避免笛卡尔积

SELECT 
    p.id,
    p.created_at,
    p.full_name,
    p.avatar_url,
    COUNT(DISTINCT q.id) AS questions_published,
    COUNT(v.question_id) AS votes_cast
FROM public.profiles p
LEFT JOIN public.questions q ON p.id = q.owner_id
LEFT JOIN public.votes v ON q.id = v.question_id
GROUP BY p.id, p.created_at, p.full_name, p.avatar_url;

方式二:子查询预统计(性能更优)

SELECT 
    p.id,
    p.created_at,
    p.full_name,
    p.avatar_url,
    COALESCE(q.question_count, 0) AS questions_published,
    COALESCE(v.total_votes, 0) AS votes_cast
FROM public.profiles p
LEFT JOIN (
    -- 预统计每个用户发布的问题数
    SELECT owner_id, COUNT(*) AS question_count
    FROM public.questions
    GROUP BY owner_id
) q ON p.id = q.owner_id
LEFT JOIN (
    -- 预统计每个用户发布的问题收到的总票数
    SELECT q.owner_id, COUNT(v.question_id) AS total_votes
    FROM public.questions q
    LEFT JOIN public.votes v ON q.id = v.question_id
    GROUP BY q.owner_id
) v ON p.id = v.owner_id;

验证结果

执行上述任意SQL,均可得到符合预期的汇总结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:40:24