我有以下代码:
@posts = Post.joins(:user).joins(:blog).select
这个查询旨在查找所有的帖子并返回关联用户和博客。
然而,用户是可选的,这意味着:joins
生成的INNER JOIN
没有返回很多记录。
我该如何将其改为生成LEFT OUTER JOIN
?
我有以下代码:
@posts = Post.joins(:user).joins(:blog).select
这个查询旨在查找所有的帖子并返回关联用户和博客。
然而,用户是可选的,这意味着:joins
生成的INNER JOIN
没有返回很多记录。
我该如何将其改为生成LEFT OUTER JOIN
?
@posts = Post.joins("LEFT OUTER JOIN users ON users.id = posts.user_id").
joins(:blog).select
@posts = Post.joins("LEFT OUTER JOIN users ON users.id = posts.user_id").joins(:blog).where("users.id IS NULL").select
- Linus Oleanderselect('posts.*')
吗? - Kevin Sylvestre你可以使用includes
来实现这个,具体请查看Rails指南上的文档:
Post.includes(:comments).where(comments: {visible: true})
结果为:
SELECT "posts"."id" AS t0_r0, ...
"comments"."updated_at" AS t1_r5
FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id"
WHERE (comments.visible = 1)
includes
函数会根据使用情境有两种不同的作用。如果你阅读第12节的全部内容,Rails指南将比我更好地解释它:http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations - WuTangTanWHERE
字句,includes
将生成两个查询而不是一个JOIN
,这只回答了问题的一部分。 - Rodriguereferences(:comments)
。此外,由于includes
,这将导致所有返回的评论都被急切地加载到内存中,这可能不是您想要的。 - Derek PriorPost.includes(:comments).where(comments: {visible: true})
。这样你也不需要使用 references
。 - michael使用eager_load
:
@posts = Post.eager_load(:user)
ActiveRecord::Base#joins
时,它将执行一个INNER JOIN。您需要传递一个表示LEFT OUTER JOIN的字符串。
:joins
- 要么是用于额外连接的SQL片段,例如"LEFT JOIN comments ON comments.post_id = id
"(很少需要),要么是与:include
选项使用相同形式的命名关联,这将在相关表上执行INNER JOIN,或者是包含字符串和命名关联混合的数组。如果值是字符串,则记录将以只读方式返回,因为它们具有不对应于表列的属性。传递
:readonly => false
以覆盖此行为。
在ActiveRecord中有一个left_outer_joins方法。您可以像这样使用它:
@posts = Post.left_outer_joins(:user).joins(:blog).select
好消息,Rails 5现在支持 LEFT OUTER JOIN
。你的查询语句现在应该是这样的:
@posts = Post.left_outer_joins(:user, :blog)
class User < ActiveRecord::Base
has_many :friends, :foreign_key=>"u_from",:class_name=>"Friend"
end
class Friend < ActiveRecord::Base
belongs_to :user
end
friends = user.friends.where(:u_req_status=>2).joins("LEFT OUTER JOIN users ON users.u_id = friends.u_to").select("friend_id,u_from,u_to,u_first_name,u_last_name,u_email,u_fbid,u_twtid,u_picture_url,u_quote")