- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
假设我们有用户:
class User < ActiveRecord::Base
has_many :connections
has_many :groups, through: :connections
end
和组:
class Group < ActiveRecord::Base
has_many :connections
has_many :users, through: :connections
end
基本上,标准的多对多连接:
class Connection
belongs_to :user
belongs_to :group
end
我打算做的是:
[4,5,6]
的组)的用户[1,2,3]
) 且不属于另一组 ([4,5,6]
>)此外,我不想:
User.joins(:group).where(group_id: [1,2,3]).where.not(group_id: [4,5,6])
和他们返回错误的结果(结果集中的一些用户属于组 4、5、6 以及 1、2、3)join
,因为我知道这对于 DB 来说是一个非常复杂的(即 CPU/内存密集型)操作<最佳答案
此类问题在 Rails 初级到中级开发人员中很常见。你知道 ActiveRecord
接口(interface)和基本的 SQL
操作,但你无意中遇到了问题中概述的这类任务。 (此类问题的几个示例:1、2)。
答案很简单:使用 SQL EXISTS
condition .来自给定 URL 的快速引用:
Syntax
The syntax for the SQL EXISTS condition is:
WHERE EXISTS ( subquery );
Parameters or Arguments
subquery
The subquery is a
SELECT
statement. If the subquery returns at least one record in its result set, theEXISTS
clause will evaluate to true and theEXISTS
condition will be met. If the subquery does not return any records, theEXISTS
clause will evaluate to false and theEXISTS
condition will not be met.
还提到 EXISTS
可能比 JOIN
慢,但这通常不是真的。来自Exists v. Join关于 SO 的问题:
EXISTS
is only used to test if a subquery returns results, and short circuits as soon as it does.JOIN
is used to extend a result set by combining it with additional fields from another table to which there is a relation. [...] If you have proper indexes, most of the time theEXISTS
will perform identically to theJOIN
. The exception is on very complicated subqueries, where it is normally quicker to useEXISTS
.
因此,数据库不需要查看所有连接(一旦找到正确的连接,它就会停止“连接”记录与“存在”),也不需要返回所有字段连接表(只需检查相应的行是否存在)。
回答具体问题:
Select only such users, who don't belong to given set of Groups (groups with ids
[4,5,6]
)
not_four_to_six = User.where("NOT EXISTS (
SELECT 1 FROM connections
WHERE connections.user_id = users.id
AND connections.group_id IN (?)
)", [4,5,6])
Select only such users, who belong to one set of Groups (
[1,2,3]
) and don't belong to another ([4,5,6]
)
one_two_three = not_four_to_six.where("EXISTS (
SELECT 1 FROM connections
WHERE connections.user_id = users.id
AND connections.group_id IN (?)
)", [1,2,3])
Select only such users, who doesn't belong to a Group
User.where("NOT EXISTS (
SELECT 1 FROM connections
WHERE connections.user_id = users.id
)")
关于sql - rails : How to Select Records Which Don't Have a Specific Related (associated) Object (SQL EXISTS brief how-to),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32016346/
我是一名优秀的程序员,十分优秀!