2014-02-23 11 views
8

Ich habe eine einfache Beziehung zwischen User und Donations in dem ein Benutzer viele Spenden hat, und eine Spende gehört einem Benutzer. Was ich tun möchte, ist eine Liste der Benutzer, geordnet nach den letzten Spenden.Distinct Records mit Joins und Bestellung

Hier ist, was ich versuche:

Zuerst habe ich die Gesamtzahl der Unik Benutzer erhalten möchten, die wie erwartet funktioniert:

> User.joins(:donations).order('donations.created_at').uniq.count 
    (3.2ms) SELECT DISTINCT COUNT(DISTINCT "users"."id") FROM "users" INNER JOIN "donations" ON "donations"."user_id" = "users"."id" 
=> 384 

Als nächstes, wenn ich das count Verfahren zu entfernen, ich erhalte eine Fehlermeldung, dass „ORDER BY-Ausdrücke in der Auswahlliste erscheinen müssen“:

> User.joins(:donations).order('donations.created_at').uniq 
    User Load (0.9ms) SELECT DISTINCT "users".* FROM "users" INNER JOIN "donations" ON "donations"."user_id" = "users"."id" ORDER BY donations.created_at 
PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list 
LINE 1: ...ON "donations"."user_id" = "users"."id" ORDER BY donations.... 

Dann habe ich versucht, indem explizit den Postgres Fehler Festsetzung settin g die SELECT-Klausel auf den ersten Blick, die scheint zu funktionieren:

> User.select('DISTINCT "users".id, "users".*, "donations".created_at').joins(:donations).order('donations.created_at') 
    User Load (17.6ms) SELECT DISTINCT "users".id, "users".*, "donations".created_at FROM "users" INNER JOIN "donations" ON "donations"."user_id" = "users"."id" ORDER BY donations.created_at 

Allerdings kehrte die Anzahl der Datensätze übernehmen nicht die DISTINCT-Anweisung berücksichtigt und 692 Datensätze zurückgibt:

> _.size 
=> 692 

Wie kann ich Erhalte die erwartete Anzahl an Ergebnissen (384) und sortiere nach dem Zeitstempel created_at der Spende.

+0

Ich nehme an, wenn Sie 'DISTINCT" Benutzer sagen ".id," Benutzer ". *," Spenden ".created_at' Server interpretiert dies als: ein Ergebnis für jedes Element, das in all seinen Feldern eindeutig ist – juanpastas

Antwort

18

Try this:

User.select('users.*,MAX(donations.created_at) as most_recent_donation'). 
    joins(:donations).order('most_recent_donation desc').group('users.id') 

Ich nehme ein Benutzer viele Spenden hat dies die jüngste erstellte Spende wählen würde und verschiedene Benutzer durch ihre ID-Filterung wählen würde.

Ich habe dies jedoch nicht getestet.

+2

Verwenden von' Gruppe ('users.id') 'Ich bekomme eine Postgres-Fehler Spalte" donations.created_at "muss in der GROUP BY-Klausel erscheinen oder in einer Aggregatfunktion verwendet werden" –

+2

Ihre aktualisierte Antwort hat bei mir funktioniert, danke! Die einzige Änderung, die ich vorgenommen habe, war die Verwendung von 'order ('most_recent_donation DESC')' weil ich dies mit [Kaminari Paginierung] (https://github.com/amatsuda/kaminari) verwende und die neuesten Spender zuerst wollte. –

+0

ah Ich verstehe, nett. – juanpastas