2016-08-01 7 views
0

Es gibt 2 Tabellen: Benutzer und Lehrer. Teacher.user_id stammt von Benutzer. Also, wie finde ich in einer einzigen Abfrage alle Benutzer, die nicht in Lehrern sind.Datensätze abrufen, auf die in keiner anderen Tabelle verwiesen wird, ActiveRecord query

bedeuten, dass ich etwas entlang der Linien:

  User.not_in(Teacher.all) 
+1

Sind Sie sicher, dass Sie nicht "Datenbanktabelle" statt "Datenbank" meinen? –

+0

Hoppla. Das ist es was ich meinte. Ich bin ein Rails Newbie. Also, ich benutze es alle austauschbar –

Antwort

0

Sie where.not Abfrage von ActiveRecord etwas versuchen, wie unten verwenden:

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

Hinweis: verwendet reject Methode, falls Sie in einigen Datensätzen keine Werte haben.

+1

So funktioniert einwandfrei. Danke vielmals. –

+0

Froh, dass es funktioniert, aber ich würde auch empfehlen, andere Antwort http://stackoverflow.com/a/38706214/2545197 ebenso zu betrachten. – Abhinay

+1

Es scheint, dass Sie in der Annahme korrekt waren, dass dies nicht Schienen 3 war, obwohl ich in diesem Fall immer noch in Betracht ziehen würde, was wir in meinem Beitrag diskutiert, denn wenn die Lehrer-Tabelle zu groß wird das SQL fehlschlagen, da eine Abfrage nur so viele sein kann Zeichen lang und das 'Array' kann dazu führen, dass es dieses überschreitet. Eine einfache Lösung ist, die Zupf-Version in 'Teacher.where.not (id: nil) .select (: user_id)' zu ändern, dann wird der "reject" -Teil stattdessen als Unterabfrage ausgeführt. – engineersmnky

0

Ich denke, sollten Sie in der Lage sein, so etwas wie dies zu tun

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

Dies wird nicht funktionieren, sollten Sie 'user_id' statt 'teacher_id' übergeben – Abhinay

1

Die anderen Nutzer scheinen die Schienen 3 Tag vernachlässigt haben (da auf der Grundlage der genehmigten Antwort entfernt Meine Antwort für die Nachwelt links.): Bitte versuchen Sie diese

User.where("id NOT IN (?)",Teacher.pluck(:user_id).join(",")) 

Dies wird SELECT * FROM users WHERE id NOT IN (....) (zwei Abfragen werden eins zu Holen Sie sich die user_id von den Lehrern und eine andere, um die user (s) nicht in der Liste zu bekommen) und kann basierend auf der Größe der Lehrer Tabelle fehlschlagen.

Andere Option ist eine Arel Tabelle:

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

Dieses ähnlich eine einzelne Abfrage erzeugen sollte

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

(eine Abfrage bessere Leistung) * Syntax nicht vollständig

getestet wurde eine weitere einzelne Abfrage-Option könnte

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

Hey, ich stimme Ihren Ansichten hier vollkommen zu, aber laufen nicht immer zwei Abfragen? – Abhinay

+0

@Abhinay es erfordert nicht, SQL zu dem Programm zurückzukehren, ein'Array' zu erstellen und dann eine zweite Abfrage auszuführen, wo die 'pluck' Methode dies erfordert. Stattdessen wird die gesamte Abfrage auf dem SQL-Server ausgeführt und nur das erforderliche Ergebnis zurückgegeben. Aber technisch könnte man die Unterabfrage als zweite Abfrage sehen, also meinen dritten Vorschlag eingeben, der wirklich 1 Abfrage ist. – engineersmnky

+0

Verstanden, danke für die Erklärung. Übrigens bezweifle ich, dass der Benutzer, der diese Frage gestellt hat, dass er wirklich Rails-3-Version meinte. Er hat erwähnt, dass er ein Neuling ist – Abhinay