web-dev-qa-db-fra.com

Postgres: Distinct mais seulement pour une colonne

J'ai un tableau sur pgsql avec des noms (ayant plus de 1 million de lignes), mais j'ai aussi beaucoup de doublons. Je sélectionne 3 champs: id, name, metadata.

Je veux les sélectionner au hasard avec ORDER BY RANDOM() et LIMIT 1000, je fais donc plusieurs étapes pour économiser de la mémoire dans mon PHP script.

Mais comment puis-je faire pour que cela ne me donne qu'une liste sans doublons dans les noms.

Par exemple [1,"Michael Fox","2003-03-03,34,M,4545"] sera retourné mais pas [2,"Michael Fox","1989-02-23,M,5633"]. Le champ de nom est le plus important et doit être unique dans la liste à chaque fois que je fais la sélection et il doit être aléatoire.

J'ai essayé avec GROUP BY name, mais il s’attend à ce que j’ai un identifiant et des métadonnées dans le GROUP BY aussi bien ou dans une fonction d'agrégation, mais je ne veux pas les filtrer d'une manière ou d'une autre.

Quelqu'un sait comment récupérer plusieurs colonnes mais ne fait qu'une seule sur une colonne?

102
NovumCoder

Pour faire une distinction sur une seule (ou n) colonne (s):

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

Cela renverra toutes les lignes contenant le nom. Si vous souhaitez contrôler laquelle des lignes sera renvoyée, vous devez commander:

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

Renverra la première ligne lorsque commandé par col1.

distinct on :

SELECT DISTINCT ON (expression [ ...]) conserve uniquement la première ligne de chaque ensemble de lignes où les expressions données sont considérées comme égales. Les expressions DISTINCT ON sont interprétées selon les mêmes règles que pour ORDER BY (voir ci-dessus). Notez que la "première ligne" de chaque ensemble est imprévisible, sauf si ORDER BY est utilisé pour garantir que la ligne souhaitée apparaît en premier.

Les expressions DISTINCT ON doivent correspondre aux expressions ORDER BY les plus à gauche. La clause ORDER BY contient normalement des expressions supplémentaires qui déterminent la priorité souhaitée pour les lignes dans chaque groupe DISTINCT ON.

189
Clodoaldo Neto

Quelqu'un sait comment récupérer plusieurs colonnes mais ne fait qu'une seule sur une colonne?

Vous voulez la clause DISTINCT ON .

Vous n'avez pas fourni d'exemple de données ni de requête complète, je n'ai donc rien à vous montrer. Vous voulez écrire quelque chose comme:

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

Cela renverra un ensemble de lignes imprévisible (mais pas "aléatoire"). Si vous voulez le rendre prévisible, ajoutez un ORDER BY Par réponse de Clodaldo. Si vous voulez le rendre vraiment aléatoire, vous aurez envie de ORDER BY random().

16
Craig Ringer
SELECT NAME,MAX(ID) as ID,MAX(METADATA) as METADATA 
from SOMETABLE
GROUP BY NAME
4
David Jashi