2013-01-09 9 views
6

Questo sembra più difficile di quanto dovrebbe essere:Postgres Rails SELECT DISTINCT con l'Ordine

Voglio essere in grado di ordinare una tabella da esso è copy_count, quindi selezionare solo gli eventi con un titolo unico, e limitare tale query per la prima 99.

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

questo genera un errore:

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

che suggeriscono ho bisogno di aggiungere il copy_count al DISTINCT ON, ma questo sarebbe anche solo tirare indietro unico registra copy_count WHI ch potrebbe essere lo stesso!

Nota: l'ordine per il conteggio delle copie DEVE verificarsi prima.

Grazie

+0

Quindi, vuoi 99 'events.title' con il più alto 'copy_count' senza duplicato' events.title'? –

+0

Che è corretto – jay

risposta

9

Per la SQL puro che sarà simile:

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 

Ma non so, come scrivere in RoR.

+5

Sarebbe bello convertirlo in sintassi AR/Arel. – freemanoid

+1

sì la domanda specifica Rails - qualcuno sa come specificarlo con l'interfaccia di AR Query? – Todd

4

Prova questo:

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

Significa che ORDER BY deve essere "events.title, copy_count DESC". DISTINCT ON richiede che la prima cosa su cui si ordina sia la lista di colonne che sono DISTINCT. Se stai cercando di ottenere il risultato più alto per titolo, devi raggrupparli in gruppi di file con lo stesso titolo prima di poter quindi ordinare per copy_count. Se non è quello che stai cercando di fare, DISTINCT ON non è il costrutto corretto.

1

Prova questa:

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

Questo accade perché quando si utilizza l'istruzione DISTINCT ON, è necessario utilizzare la sua espressione (ad esempio events.title) nella ORDER BY espressioni

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

Così, è sufficiente aggiungere la colonna copy_count subito dopo events.title nell'istruzione dell'ordine

0

Questo è quello che ho provato:

Event.select('events.copy_count, RANDOM()').order('Random()').limit(10) 
Problemi correlati