2013-01-09 11 views
6

Dies scheint schwieriger, als es sein sollte:Postgres Rails Distinct Wählen Sie mit Bestell

Ich möchte eine Tabelle sortieren können, indem sie es copy_count ist, dann werden nur Ereignisse mit einem eindeutigen Titel auszuwählen und zu begrenzen, dass die Abfrage an den ersten 99.

Event.order("copy_count DESC").select("DISTINCT ON (events.title) *").limit(99) 

Dies wirft einen Fehler:

ActiveRecord::StatementInvalid: PG::Error: ERROR: SELECT DISTINCT ON expressions must match initial ORDER BY expressions 

Welche schlage ich die copy_count zum DISTINCT ON hinzufügen müssen, aber dies würde WHI auch nur zurückziehen einzigartige copy_count Aufzeichnungen ch könnte gleich sein!

Hinweis: Die Reihenfolge nach dem copy_count MUSS zuerst passieren.

Dank

+0

Also wollen Sie 99 'events.title' mit höchster' copy_count' ohne doppelte 'events.title'? –

+0

Das ist richtig – jay

Antwort

9

Für den reinen SQL es aussehen wird:

SELECT * 
FROM (SELECT DISTINCT ON (events.title) * 
     FROM events 
     ORDER BY events.title, events.copy_count DESC) top_titles 
ORDER BY events.copy_count DESC 
LIMIT 99 

Aber ich weiß nicht, wie es in RoR zu schreiben.

+5

Wäre toll, es in AR/Arel-Syntax zu konvertieren. – freemanoid

+1

ja die Frage gibt Rails an - weiß jemand, wie man das mit AR Query Schnittstelle spezifiziert? – Todd

4

Versuchen Sie folgendes:

Event.order("copy_count DESC").limit(99).select(:title).uniq 
2

Es bedeutet, dass die ORDER BY-Bedürfnisse "events.title, copy_count DESC" zu sein. DISTINCT ON erfordert, dass das erste, was Sie sortieren, die Liste der Spalten ist, die DISTINCT sind. Wenn Sie versuchen, das höchste Ergebnis pro Titel zu erzielen, müssen Sie sie zuerst in Gruppen von Zeilen mit demselben Titel gruppieren, bevor Sie sie nach copy_count sortieren können. Wenn Sie das nicht versuchen, ist DISTINCT ON nicht das richtige Konstrukt.

1

Try this:

Event.select("DISTINCT ON (events.title) *").order("events.title, copy_count DESC").limit(99) 

Dies geschieht, weil, wenn Sie die Anweisung DISTINCT ON verwenden, müssen Sie seinen Ausdruck (zB events.title) in der ORDER BY-Ausdrücke

SQL ERROR: SELECT DISTINCT ON expressions must match initial ORDER BY expressions 

So Sie müssen nur die copy_count Spalte direkt nach dem events.title in der Auftragsstatement

0

hinzufügen Das ist, was ich versucht habe:

Event.select('events.copy_count, RANDOM()').order('Random()').limit(10) 
Verwandte Themen