背景:
我正在使用Rails和Postgres简单地克隆黑客新闻。我已经完成了大部分工作,而且我正在努力允许网站访问者按照分数对文章进行排序。就目前而言,我有主要工作。这是相关的代码:
Article.select("articles.*, SUM( CASE votes.is_up WHEN FALSE THEN -1 ELSE 1 END ) AS score")
.joins("LEFT JOIN votes ON articles.id = votes.votable_id AND votes.votable_type = 'Article'")
.group("articles.id")
.order("score DESC")
正如您可能知道的那样,这有一个问题:没有得分的文章没有正确排序(至少有一个问题无论如何 - 我不是一个SQL专业人员)。例如,如果我的文章的分数为2,-1,5和0,则顺序为0, 5, 2, -1
,而不是5, 2, 0, -1
的正确顺序。
问题:
我认识到这样做的最简单/最好的方法可能就是在score
上添加一个articles
列 - 我很可能会走这条路 - 但这让我非常感兴趣好奇:有没有办法将score
的默认值设为articles
而没有关联的votes
?
更新1:
根据建议,我已将select语句更改为:
Article.select("articles.*, COALESCE( SUM( CASE votes.is_up WHEN FALSE THEN -1 ELSE 1 END ), 0) AS score")
然而,这根本没有改变结果。
更新2:
运行查询时生成的SQL:
SELECT articles.*, COALESCE(SUM( CASE votes.is_up WHEN FALSE THEN -1 ELSE 1 END ), 0) AS score
FROM "articles" LEFT JOIN votes ON articles.id = votes.votable_id AND votes.votable_type = 'Article'
GROUP BY articles.id
ORDER BY score DESC
LIMIT 20
OFFSET 0
您还可以看到我用于分页的LIMIT
和OFFSET
- 我之前没有提到这一点,因为我预计它不相关。
答案 0 :(得分:0)
您似乎只是获得了NULL,因此需要COALESCE
将其转换为0;
Article.select(
"articles.*, COALESCE(SUM( CASE votes.is_up WHEN FALSE THEN -1 ELSE 1 END ), 0) AS score")
...