按关联排序时设置默认值

时间:2014-09-29 03:50:37

标签: sql ruby-on-rails ruby postgresql

背景:

我正在使用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

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

1 个答案:

答案 0 :(得分:0)

您似乎只是获得了NULL,因此需要COALESCE将其转换为0;

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