2012-03-15 51 views
0

我正在放置一个Rails应用程序,并且遇到了一些SQL障碍。虽然它可以在Sqlite3中解决,但当我将它移动到运行Postgres的Heroku服务器时,它会窒息而死。情况如下:SQL Group By和Order By具有集合函数

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); 

在任何可敬的DB,有关集合函数此查询哼唧等什么是做到这一点的最好方法是什么?我最好在Sports表中保留一个“投票”字段,并在投票时更新这个字段? Sports_Vote表还记录了提交投票的用户的ID,因此它是必需的。其次,我想在理想情况下合并两张相似的表格,以便按票数降序排列体育和曲奇(曲棍球排名第一,枫树曲奇#2,足球#3,等等)。有什么建议?

回答

4

经验法则,以避免错误使用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); 

OR

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); 

要使用第二个表合并和排名,你可以只使用union(该order 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),但它会降低投票的性能(因为现在必须插入AND更新一秒表)。所以这取决于你的优先事项。

+1

非常感谢@Diego。这似乎有伎俩。一个快速跟进:在Rails控制器中最好的方法是什么? – opticon 2012-03-15 01:52:15