我正在整理一个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_Vote表还记录了提交投票的用户的ID,因此需要它。
其次,我想理想地将两个相似的表组合在一起,这样我就能得到一个很好的名单,运动和饼干按照投票的降序排列(曲棍球排名第一,枫树饼干#2,足球#3等等) )。有什么建议吗?
答案 0 :(得分: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 by
和inner join
),但会降低投票的性能(从现在开始)你必须插入和更新第二个表)。所以这取决于你的优先事项。