Was ist der beste Weg, um mit Postgres und Activerecord Datensätze mit doppelten Werten über mehrere Spalten hinweg zu finden?
Ich habe diese Lösung hier gefunden :
User.find(:all, :group => [:first, :email], :having => "count(*) > 1" )
Aber mit Postgres scheint es nicht zu funktionieren. Ich erhalte diesen Fehler:
PG :: GroupingError: ERROR: Die Spalte "parts.id" muss in der GROUP BY-Klausel erscheinen oder in einer Aggregatfunktion verwendet werden
ruby-on-rails
postgresql
activerecord
newUserNameHere
quelle
quelle
select a.id, b.id, name, email FROM user a INNER JOIN user b USING (name, email) WHERE a.id > b.id
. Keine Ahnung, wie man das in ActiveRecord-speak ausdrückt.Antworten:
Getestete & Arbeitsversion
Auch dies ist ein wenig unabhängig, aber praktisch. Wenn Sie sehen möchten, wie oft jede Kombination gefunden wurde, setzen Sie am Ende .size:
und Sie erhalten eine Ergebnismenge, die folgendermaßen aussieht:
Ich fand das ziemlich cool und hatte es noch nie gesehen.
Dank an Taryn, dies ist nur eine optimierte Version ihrer Antwort.
quelle
select()
wie in übergeben:User.select([:first,:email]).group(:first,:email).having("count(*) > 1").count
um zu arbeiten..count
gibtPG::UndefinedFunction: ERROR: function count
.size
anstelle von.count
Dieser Fehler tritt auf, weil Sie bei POSTGRES Gruppierungsspalten in die SELECT-Klausel einfügen müssen.
Versuchen:
(Hinweis: nicht getestet, möglicherweise müssen Sie es optimieren)
BEARBEITET, um die ID-Spalte zu entfernen
quelle
id
Spalte ist nicht Teil der Gruppe, daher können Sie sie nur referenzieren, wenn Sie sie aggregieren (z. B.array_agg(id)
oderjson_agg(id)
)Wenn Sie die vollständigen Modelle benötigen, versuchen Sie Folgendes (basierend auf der Antwort von @ newUserNameHere).
Dadurch werden die Zeilen zurückgegeben, in denen die E-Mail-Adresse der Zeile nicht eindeutig ist.
Mir ist keine Möglichkeit bekannt, dies über mehrere Attribute hinweg zu tun.
quelle
.select(:email)
überflüssig ist. Ich denke, das ist ein bisschen sauberer, aber ich könnte mich irren.User.where(email: User.select(:email).group(:email).having("count(*) > 1"))
Holen Sie sich alle Duplikate mit einer einzigen Abfrage, wenn Sie PostgreSQL verwenden :
quelle
Basierend auf der obigen Antwort von @newUserNameHere glaube ich, dass der richtige Weg ist, die Anzahl für jeden zu zeigen
quelle