2016-08-01 13 views
0

ユーザと教師の2つのテーブルがあります。 Teacher.user_idはUserのものです。だから、どのように私は単一のクエリで、教師にいないすべてのユーザーを見つけることができます。他のテーブルで参照されていないレコード、ActiveRecordクエリ

私は線に沿って何か意味:私はあなたがあなたがActiveRecordからwhere.notクエリを使用することができ、この

User.where.not(id: Teacher.ids) 
+1

「データベース」ではなく「データベーステーブル」を意味するのではないですか? –

+0

それが私の言いたいことです。私はレール初心者です。だから、私はすべてそれを相互交換可能に使用する –

答えて

0

ような何かを行うことができるはずだと思う

  User.not_in(Teacher.all) 
+1

こうして完璧に動作します。どうもありがとう。 –

+0

うれしかったですが、私はまた他の答えを検討することをお勧めしますhttp://stackoverflow.com/a/38706214/2545197同様に。 – Abhinay

+1

これはレール3ではないと仮定して正しいと思われますが、このイベントで私は私の投稿で議論した内容を考慮に入れていますが、教師のテーブルが大きくなりすぎると、 'Array'はこれを超えてしまいます。シンプルな解決策は、抜粋バージョンを 'Teacher.where.not(id:nil).select(:user_id)'に変更することです。代わりに 'reject'部分をサブクエリとして実行します。 – engineersmnky

0

は、以下のようなものを試してください:

User.where.not(id: Teacher.pluck(:user_id).reject {|x| x.nil?}) 

注:rejectメソッドを使用し、いくつかのレコードにnil値がある場合に備えます。

+0

これはうまくいかない、 'teacher_id'の代わりに' user_id'を渡すべきである – Abhinay

1

他のユーザーが(承認された回答に基づいて削除するので私の答えは、後世のために残しました。)レール3のタグを無視しているように見える:この

を試してみてください
User.where("id NOT IN (?)",Teacher.pluck(:user_id).join(",")) 

これはSELECT * FROM users WHERE id NOT IN (....)(2つのクエリ1がになります教師からuser_idを取得し、別の人はuserを取得してください)、教師用テーブルのサイズに基づいて失敗する可能性があります。

その他のオプションは、ARELテーブルです:

users = User.arel_table 
User.where(users[:id].not_in(Teacher.select(:user_id).where("user_id IS NOT NULL"))) 

これは*構文は完全に

別にテストされませんでした(1つのクエリより良い性能)

SELECT * FROM users 
WHERE id NOT IN (SELECT user_id FROM teachers WHERE user_id IS NOT NULL) 

に似た単一のクエリを生成する必要があります単一のクエリオプションは、

User.joins("LEFT OUTER JOIN teachers ON teachers.user_id = users.id"). 
    where("teachers.user_id IS NULL") 
+0

ねえ、私はここであなたの意見に完全に同意しますが、まだ2つのクエリを実行していませんか? – Abhinay

+0

@Abhinay SQLはプログラムに戻り、 'Array'をビルドしてから、' pluck'メソッドが必要とするところで2番目のクエリを実行する必要はありません。代わりにSQLサーバー上でクエリ全体が実行され、必要な結果のみが返されます。しかし、技術的には、サブクエリを2番目のクエリーとして見ることができ、3番目の提案は本当に1つのクエリーになります。 – engineersmnky

+0

説明してくれてありがとう。 btw私は彼が本当にレール3バージョンを意味するのか疑問に思ったこの質問をしているユーザーを与えられた方法。彼は初心者であることについて言及した – Abhinay

関連する問題