2013-06-04 17 views
64

Ho una tabella su pgsql con nomi (con più di 1 milione di righe), ma ho anche molti duplicati. Seleziono 3 campi: id, name, metadata.Postgres: distinto ma solo per una colonna

Voglio selezionarli a caso con ORDER BY RANDOM() e LIMIT 1000, quindi faccio questo è molti passaggi per risparmiare un po 'di memoria nel mio script PHP.

Ma come posso farlo in modo che mi dia solo una lista senza duplicati nei nomi.

Ad esempio [1,"Michael Fox","2003-03-03,34,M,4545"] verrà restituito ma non [2,"Michael Fox","1989-02-23,M,5633"]. Il campo del nome è il più importante e deve essere univoco nell'elenco ogni volta che eseguo la selezione e deve essere casuale.

ho provato con GROUP BY name, BU quindi si aspetta me avere id e metadati nel GROUP BY come bene o in una funzione aggragate, ma io non voglio avere in qualche modo filtrati.

Qualcuno sa come recuperare molte colonne ma solo una distinta su una colonna?

risposta

135

Per fare un distinto su un solo (o n) della colonna (s):

select distinct on (name) 
    name, col1, col2 
from names 

Ciò restituirà una delle righe che contengono il nome. Se si desidera controllare quali delle righe verrà restituita è necessario ordinare:

select distinct on (name) 
    name, col1, col2 
from names 
order by name, col1 

restituirà la prima fila quando ordinato da col1.

distinct on:

SELECT DISTINCT ON (espressione [, ...]) mantiene solo la prima riga di ciascun gruppo di righe in cui le espressioni date restituiscono uguali. Le espressioni DISTINT ON sono interpretate usando le stesse regole di ORDER BY (vedi sopra). Si noti che la "prima riga" di ciascun set è imprevedibile a meno che non venga utilizzato ORDER BY per assicurarsi che la riga desiderata venga visualizzata per prima.

Le espressioni DISTINCT ON devono corrispondere alle espressioni ORDER BY più a sinistra. La clausola ORDER BY conterrà normalmente espressioni (s) aggiuntive che determinano la precedenza desiderata delle righe all'interno di ciascun gruppo DISTINCT ON.

+0

Buona cattura all'ordine. Non l'ho incluso perché hanno menzionato la necessità di un ordinamento casuale, ma è importante menzionarlo comunque. –

+0

sì, l'ordine è anche importante, grazie. – NovumCoder

+0

È richiesto l'ordine per nome? Produrrebbe un risultato diverso con 'order by col1'? –

2
SELECT NAME,MAX(ID) as ID,MAX(METADATA) as METADATA 
from SOMETABLE 
GROUP BY NAME 
+2

Solo una parola di cautela: che potrebbe non restituire il valore ID o il valore dei metadati che appartengono "insieme" –

+0

Hm quindi questo significa che SQL non è corretto? – NovumCoder

+0

@Novum No. Significa che il gatto prende un valore di id da una delle righe di Michael e i metadati da un altro come richiesto per i massimi di Michael. –

12

qualcuno sa come recuperare molte colonne, ma solo fare una netta su una colonna?

Si desidera the DISTINCT ON clause.

Non hai fornito dati di esempio o una query completa, quindi non ho nulla da mostrare. Si vuole scrivere qualcosa di simile:

SELECT DISTINCT ON (name) fields, id, name, metadata FROM the_table; 

Ciò restituirà un set imprevedibile (ma non "casuale") di righe. Se vuoi renderlo prevedibile aggiungi un ORDER BY per risposta di Clodaldo. Se vuoi renderlo veramente casuale, ti consigliamo di effettuare il ORDER BY random().

Problemi correlati