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

基于Group By关联poll_opts与poll_voted两张投票数据表的技术问询

基于GROUP BY关联poll_opts与poll_voted表的实现方案

没问题,我来帮你实现这个基于GROUP BY关联两张投票表的操作。结合你的表结构,给你几个实用的SQL示例,还有关键细节的说明:

基础需求:统计每个投票选项的得票数

这是最常用的场景——统计指定投票(或所有投票)中每个选项的实际投票人数:

SELECT 
    po.pid,
    po.oid,
    po.opt AS option_text,
    COUNT(pv.emp) AS vote_count
FROM poll_opts po
-- 使用LEFT JOIN确保没人投票的选项也能被保留(显示0票)
LEFT JOIN poll_voted pv 
    ON po.pid = pv.pid 
    AND po.oid = pv.oid
-- 可选:添加WHERE子句指定单个投票ID,去掉则统计所有投票的选项
WHERE po.pid = 1
GROUP BY po.pid, po.oid, po.opt
ORDER BY po.pid, po.oid;

关键细节说明:

  • LEFT JOIN的必要性:如果用INNER JOIN,那些还没有任何投票的选项会被过滤掉;LEFT JOIN会保留poll_opts里的所有选项,没有投票的选项对应的vote_count会显示为0。
  • COUNT(pv.emp)而非COUNT(*):LEFT JOIN中未被投票的选项对应的pv字段都是NULL,COUNT(*)会把这些NULL行也统计成1,而COUNT(pv.emp)只会统计非NULL的投票记录,得到真实的得票数。
  • GROUP BY的字段选择:因为poll_opts的主键是(pid, oid),这两个字段已经能唯一标识一个选项;加上opt是为了在结果中显示选项文本,符合大多数SQL数据库的GROUP BY规则(非聚合字段必须出现在GROUP BY中)。

进阶需求:统计每个投票的选项得票占比

如果需要同时展示每个选项在所属投票中的得票百分比,可以结合窗口函数实现:

SELECT 
    po.pid,
    po.oid,
    po.opt AS option_text,
    COUNT(pv.emp) AS vote_count,
    -- 计算当前选项在所属投票中的得票占比(保留2位小数)
    ROUND(COUNT(pv.emp) * 100.0 / SUM(COUNT(pv.emp)) OVER (PARTITION BY po.pid), 2) AS vote_percentage
FROM poll_opts po
LEFT JOIN poll_voted pv 
    ON po.pid = pv.pid 
    AND po.oid = pv.oid
GROUP BY po.pid, po.oid, po.opt
ORDER BY po.pid, vote_count DESC;

这里SUM(COUNT(pv.emp)) OVER (PARTITION BY po.pid)会计算每个投票的总票数,再用当前选项的得票数除以总票数得到百分比,ROUND()函数用来控制小数位数。

注意事项

  • 一定要同时用pid和oid作为JOIN条件:因为oid仅在单个投票内唯一,单独用oid关联会导致跨投票的错误匹配。
  • 如果你的数据库开启了严格的GROUP BY模式(比如MySQL的ONLY_FULL_GROUP_BY),务必保证SELECT中的非聚合字段都出现在GROUP BY列表中,否则会报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:35:47