2014-09-29 33 views
0

背景:按关联排序时设置默认值

我正在使用Rails和Postgres制作Hacker News的简单副本。我已经完成了大部分工作,而且我正在努力让访问者通过它的分数对网站进行排序。就目前而言,我有,主要是工作。下面是相关的代码:

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为0到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

您还可以看到LIMITOFFSET,我使用的分页 - 我没有提到这一点原本是因为我预计它不相关。

+0

做一个左外连接和'聚结((SUM(票),0)' – 2014-09-29 04:08:11

+0

我从来没有碰到过'coalesce'之前,非常感谢!从看Postgres的文档,它肯定看起来像什么我想要。 你在哪里建议把左连接? – aandrea 2014-09-29 05:19:38

回答

0

看起来你只是得到NULL,所以你需要一个COALESCE将它转换为0;

Article.select(
    "articles.*, COALESCE(SUM(CASE votes.is_up WHEN FALSE THEN -1 ELSE 1 END), 0) AS score") 
... 
+0

谢谢!使用'COALESCE'绝对看起来是正确的路要走。但是,我得到了与以前完全相同的行为, Postgres文档,我觉得很奇怪,任何想法? – aandrea 2014-09-29 05:22:36

+0

@aandrea听起来很奇怪,你能不知怎么看到生成的SQL? – 2014-09-29 08:06:38

+0

我用生成的SQL更新了主帖,再次感谢! – aandrea 2014-09-29 18:57:28