Postgres: Distinto pero solo para una columna


Tengo una tabla en pgsql con nombres (que tienen más de 1 mio. filas), pero también tengo muchos duplicados. Selecciono 3 campos: id, name, metadata.

Quiero seleccionarlos aleatoriamente con ORDER BY RANDOM() y LIMIT 1000, por lo que hago estos son muchos pasos para guardar algo de memoria en mi script PHP.

Pero cómo puedo hacer eso para que solo me dé una lista que no tenga duplicados en los nombres.

Por ejemplo, se devolverá [1,"Michael Fox","2003-03-03,34,M,4545"] pero no [2,"Michael Fox","1989-02-23,M,5633"]. El campo nombre es el más importante y debe ser único en el lista cada vez que hago la selección y debe ser al azar.

Lo intenté con GROUP BY name, pero entonces espera que tenga id y metadatos en GROUP BY también o en una función aggragate, pero no quiero que se filtren de alguna manera.

¿Alguien sabe cómo obtener muchas columnas pero hacer solo una distinta en una columna?

Author: Craig Ringer, 2013-06-04

3 answers

Para hacer una distinción en solo una(o n) columna (s):

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

Esto devolverá cualquiera de las filas que contengan el nombre. Si desea controlar cuál de las filas se devolverá, debe ordenar:

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

Devolverá la primera fila cuando sea ordenada por col1.

distinct on:

SELECCIONE DISTINCT ON (expresión [,...]) mantiene solo la primera fila de cada conjunto de filas donde las expresiones dadas se evalúan como iguales. Las DISTINTAS expresiones ON son interpretadas usando las mismas reglas que para ORDER BY (ver arriba). Tenga en cuenta que la "primera fila" de cada conjunto es impredecible a menos que se use ORDER BY para garantizar que la fila deseada aparezca primero.

La(s) expresión(s) ON DISTINTA (s) debe (n) coincidir con el ORDEN más a la izquierda POR expresión (s). La cláusula ORDER BY normalmente contendrá expresiones adicionales que determinan la prioridad deseada de las filas dentro de cada grupo ON DISTINTO.

 152
Author: Clodoaldo Neto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-30 09:25:16

¿Alguien sabe cómo obtener muchas columnas pero hacer solo una distinta en una columna?

Quieres la cláusula DISTINCT ON .

No proporcionaste datos de muestra o una consulta completa, así que no tengo nada que mostrarte. Quieres escribir algo como:

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

Esto devolverá un conjunto de filas impredecible (pero no "aleatorio"). Si quieres hacerlo predecible añade un ORDER BY por respuesta de Clodaldo. Si quieres que sea realmente aleatorio, querrás ORDER BY random().

 12
Author: Craig Ringer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-28 10:29:49
SELECT NAME,MAX(ID) as ID,MAX(METADATA) as METADATA 
from SOMETABLE
GROUP BY NAME
 2
Author: David Jashi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-04 09:17:35