Jaki jest najlepszy sposób na znalezienie rekordów ze zduplikowanymi wartościami w wielu kolumnach przy użyciu Postgres i Activerecord?
Znalazłem to rozwiązanie tutaj :
User.find(:all, :group => [:first, :email], :having => "count(*) > 1" )
Ale wygląda na to, że nie działa z postgresami. Otrzymuję ten błąd:
PG :: GroupingError: ERROR: kolumna „parts.id” musi występować w klauzuli GROUP BY lub być używana w funkcji agregującej
ruby-on-rails
postgresql
activerecord
newUserNameHere
źródło
źródło
select a.id, b.id, name, email FROM user a INNER JOIN user b USING (name, email) WHERE a.id > b.id
. Nie mam pojęcia, jak wyrazić to w języku ActiveRecord.Odpowiedzi:
Wersja testowana i działająca
Jest to również trochę niezwiązane, ale przydatne. Jeśli chcesz zobaczyć, ile razy znaleziono każdą kombinację, wpisz .size na końcu:
a otrzymasz zestaw wyników, który wygląda następująco:
Pomyślałem, że to całkiem fajne i wcześniej tego nie widziałem.
Podziękowania dla Taryn, to tylko poprawiona wersja jej odpowiedzi.
źródło
select()
jak w:User.select([:first,:email]).group(:first,:email).having("count(*) > 1").count
aby działać..count
dajePG::UndefinedFunction: ERROR: function count
.size
zamiast.count
Ten błąd występuje, ponieważ POSTGRES wymaga umieszczenia kolumn grupujących w klauzuli SELECT.
próbować:
(uwaga: nie testowane, może być konieczne dostosowanie)
ZMIENIONO, aby usunąć kolumnę z identyfikatorem
źródło
id
kolumna nie jest częścią grupy, więc nie można przekazać ją chyba agregować go (nparray_agg(id)
lubjson_agg(id)
)Jeśli potrzebujesz pełnych modeli, wypróbuj następujące rozwiązania (w oparciu o odpowiedź @ newUserNameHere).
Spowoduje to zwrócenie wierszy, w których adres e-mail wiersza nie jest unikalny.
Nie znam sposobu, aby to zrobić w przypadku wielu atrybutów.
źródło
.select(:email)
jest zbędny. Myślę, że to trochę czystsze, ale mogę się mylić.User.where(email: User.select(:email).group(:email).having("count(*) > 1"))
Uzyskaj wszystkie duplikaty za pomocą jednego zapytania, jeśli używasz PostgreSQL :
źródło
Opierając się na powyższej odpowiedzi @newUserName, uważam, że właściwy sposób pokazania liczby dla każdego z nich to
źródło