【问题标题】:SQL Group By and Order By with Aggregate FunctionsSQL Group By 和 Order By 与聚合函数
【发布时间】:2012-03-15 01:37:42
【问题描述】:

我正在构建一个 Rails 应用程序,但遇到了一些 SQL 障碍。虽然它可以在 Sqlite3 中解决,但当我将它移动到运行 Postgres 的 Heroku 服务器时,它会窒息而死。情况如下:

SPORTS
-----------------------------
|   id    |      title      |
-----------------------------
|   1     |  Baseball       |
-----------------------------

SPORTS_VOTE
------------------------------------
|  id  |   sport_id    |    vote   |
------------------------------------
|  1   |       1       |     1     |
------------------------------------

投票列可以是 1 或 -1。我想要一份按总票数排序的运动列表。我在 Sqlite3 中使用的查询是这样的:

  SELECT s.title, sum(sv.vote)
    FROM sports s 
   INNER JOIN sports_vote sv ON s.id = sv.sport_id 
 GROUP BY s.id
 ORDER BY sum(sv.vote);

在任何受人尊敬的数据库中,此查询都会抱怨聚合函数等。最好的方法是什么?我最好在 Sports 表中保留一个“投票”字段,并在投票时更新它吗? Sports_Vote 表还记录了提交投票的用户的 ID,因此需要它。

其次,我想理想地组合两个相似的表格,这样我就可以得到一个很好的列表,比如体育和饼干,按投票的降序排列(曲棍球排名第一,枫糖饼干排名第二,足球排名第三,等等)。有什么建议吗?

【问题讨论】:

    标签: sql ruby-on-rails ruby


    【解决方案1】:

    使用group by 时防止错误的经验法则是:

    • 所有未聚合的列都必须包含在group by 子句中。

    因此,您的查询应该是:

     SELECT s.id, s.title, sum(sv.vote)
        FROM sports s 
       INNER JOIN sports_vote sv ON s.id = sv.sport_id 
     GROUP BY s.id, s.title
     ORDER BY sum(sv.vote);
    

     SELECT s.title, sum(sv.vote)
        FROM sports s 
       INNER JOIN sports_vote sv ON s.id = sv.sport_id 
     GROUP BY s.title
     ORDER BY sum(sv.vote);
    

    要与第二个表格和排名组合,您只需使用unionorder by 将应用于组合结果):

     SELECT s.title, sum(sv.vote) vote_count
        FROM sports s 
       INNER JOIN sports_vote sv ON s.id = sv.sport_id 
     GROUP BY s.title
     UNION   
     SELECT s.title, sum(sv.vote) vote_count
        FROM cookies s 
       INNER JOIN cookies_vote sv ON s.id = sv.sport_id 
     GROUP BY s.title
     ORDER BY vote_count DESC;
    

    关于您是否应该将投票计数保留在运动表中并在每次投票时更新的问题取决于您。这样做会在生成上述报告时为您提供更好的性能(因为不再需要 group byinner join),但它会降低投票的性能(因为现在您必须插入并更新第二个表)。所以这取决于你的优先事项。

    【讨论】:

    • 非常感谢@Diego。这似乎可以解决问题。一个快速跟进:在 Rails 控制器中实现这一点的最优雅的方法是什么?
    猜你喜欢
    • 2014-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-09
    相关资源
    最近更新 更多