【问题标题】:SQL syntax to retrieve votes strangely misses some results检索选票的 SQL 语法奇怪地遗漏了一些结果
【发布时间】:2026-02-05 00:40:01
【问题描述】:

我试图查看其他帖子来进行 Mysql 查询,我想我快到了,但由于某种原因我有一个错误。

我有那些桌子:

POSTS [id_post (int) / activity (int) ]
VOTES [id_vote (int) / id_post (int) / user_id (int)]
ACTIVITIES [id_activity (int) / activity_name (varchar)]

事实上,我有更多的表和字段,但这些与我的问题相关。我创建了一个投票系统,将用户投票添加到 VOTES 表中,参考正在投票的帖子和投票人的用户帐户。

所以投票表可能如下所示:

id_vote | id_post | user_id
   1        5         8
   2        6         8

每个帖子都属于一个活动。我想列出每项活动获得最多票数的帖子。

这就是我到目前为止的位置:

SELECT activities.id_activity, activities.activity_name, votes.id_post, votes.totalvotes AS allvotes
FROM ( SELECT votes.id_post, COUNT(*) as totalvotes
       FROM `votes`
       GROUP BY votes.id_post
     ) AS votes
JOIN posts ON posts.id_post = votes.id_post
JOIN activities ON posts.activity = activities.id_activity
GROUP BY activities.id_activity
HAVING allvotes = MAX(totalvotes)

这很好用,我检索到我想要的内容,除了如果同一活动中的 2 个帖子具有相同的票数,我不知道哪一个仅在对这些帖子进行分组后出现,以及为什么不是另一个。

id_activity | activity_name | id_post | allvotes
    5            eating          5         2
    3           sleeping         6         1

更重要的是,真正困扰我的是某些活动由于某种原因不会出现。我注意到,在上面的例子中,如果属于饮食类别的帖子 5 确实是得票最多的帖子,那么该类别就会出现。但是如果碰巧有最多票的饮食类别的帖子不是帖子 5(这是 MYSQL 决定默认显示的一个),那么关于饮食类别的整行根本不会显示.

我已经有 2 天了... 有什么想法吗?

非常感谢。

【问题讨论】:

    标签: mysql sql select count


    【解决方案1】:

    在单个查询中实现并不复杂。使用一些临时表会很容易。如果您想在单个查询中使用它,那么您可以尝试使用 row_number。

    示例:

    SELECT id_activity,activity_name,id_post,v_count FROM(
    SELECT id_activity,activity_name,id_post,v_count 
    ,@rownum := IF(@prev_value=id_activity,@rownum+1,1) AS RowNumber
    ,@prev_value := id_activity  
    FROM (
    select a.id_activity,a.activity_name,p.id_post,v.v_count
    from activities a
    left join posts p on p.activity=a.id_activity
    left join (
      select id_post,count(*) v_count from votes v1
      group by id_post
    ) v on v.id_post=p.id_post
    order by a.id_activity, v.v_count desc) as tmp
    ,(SELECT @rownum := 0) r
    ,(SELECT @prev_value := '') y
    )tmp2
    WHERE rownumber=1
    

    FIDDLE

    【讨论】:

    • 非常感谢。 2天就这样,你直接解决问题!你是老板!虽然我真的不明白你是怎么做到的(我不知道@rownum 的语法和含义。不过有一个问题。Sinc 我看到这个查询有 6 个选择,你说另一种方法是使用临时表,你会推荐使用这个查询还是临时表?我也不知道我会怎么做这个,但我可以考虑一下它是否更快?无论如何感谢一堆:)
    【解决方案2】:

    我猜是因为您按活动分组,我想知道为什么在 mysql 中允许此语句,在 mssql 中您不能仅按活动分组。在这种情况下,您必须按活动和/或 id_post 分组

    试试这个:

    SELECT activities.id_activity, activities.activity_name, votes.id_post, COUNT(*) as totalvotes
    FROM votes
    INNER JOIN posts ON posts.id_post = votes.id_post
    INNER JOIN activities ON posts.activity = activities.id_activity
    GROUP BY votes.id_post
    HAVING totalvotes = MAX(totalvotes)
    

    如果可行的话,还有 lmk :)

    或您的声明已修改:

    SELECT activities.id_activity, activities.activity_name, votes.id_post, votes.totalvotes AS allvotes
    FROM ( SELECT votes.id_post, COUNT(*) as totalvotes
           FROM `votes`
           GROUP BY votes.id_post
         ) AS votes
    JOIN posts ON posts.id_post = votes.id_post
    JOIN activities ON posts.activity = activities.id_activity
    GROUP BY votes.id_post
    HAVING allvotes = MAX(totalvotes)
    

    如果我猜对了,那是因为您有 2 个具有相同活动的帖子,一旦您对活动进行分组而不是对帖子进行分组,一个帖子就会消失。

    【讨论】:

    • 非常感谢您的快速答复,非常感谢。我尝试了两种解决方案,但现在都没有真正起作用。第一个不返回任何结果,而第二个猜测返回许多结果,但许多行显示来自同一活动的帖子。如果我按activity_id 分组,我确实只有一个显示每个活动的帖子,虽然它不是一个好帖子。如果我按 post_id 分组,我得不到我需要的东西,如果我按活动分组,然后是 id_post,它仍然显示来自同一类别的许多行。我也完全按照您的建议尝试了 HAVING 部分,它工作正常,除了一些活动没有出现