2

使用 Rails 3,这个范围可以按预期工作:

      scope :with_posts, lambda {
        joins(:posts).
        select("authors.*, count(posts.id) posts_count").
        group("posts.author_id").
        having("posts_count > 0")
      }

生成的 SQL 为:

SELECT authors.*, count(posts.id) posts_count FROM `authors` INNER JOIN `posts` ON `posts`.`author_id` = `author`.`id` GROUP BY posts.author_id HAVING posts_count > 0

但它的逆不返回任何结果:

      scope :with_posts, lambda {
        joins(:posts).
        select("authors.*, count(posts.id) posts_count").
        group("posts.author_id").
        having("posts_count < 1")
      }

我假设第三行根本没有选择零帖子的作者......那么解决方案是什么?

4

4 回答 4

1

由于正在创建内部连接 ​​SQL,它将显示结果以及两个表中都可用的记录。所以尝试创建外连接并在下一个表中查找/计算空值

尝试外连接

于 2010-10-12T04:45:15.700 回答
1

你是对的,加入排除了所有零帖子的作者,你需要的是外部加入。

我不知道 rails 3 的语法,但是在 rails 2 中,您可以使用 SQL 片段而不是简单地使用关系名称来指定 joins 语句。
User.all(:joins => 'outer join posts on users.id = posts.user_id')
Rails 3 必须有一个等价的符号,但我从未使用过它,所以我不知道确切的语法。不过,这应该是一般的想法。

于 2010-10-12T10:53:57.837 回答
0

我对此了解不多,但我建议你看看这个Railscast

希望这对你有用。

于 2010-10-12T05:57:14.310 回答
0
scope :without_posts, lambda {
    where("id NOT IN (?)", Posts.select("author_id").group("author_id") )
}

如果您的数据库中有关于 author_id 的索引,这将最有效。

于 2012-12-28T17:22:15.130 回答