2013-06-04 13 views
64

Mam tabelę na pgsql z nazwami (mającą więcej niż 1 milion wierszy), ale mam też wiele duplikatów. Wybieram 3 pola: id, name, metadata.Postgres: Wyraźny, ale tylko dla jednej kolumny

Chcę wybrać je losowo z ORDER BY RANDOM() i LIMIT 1000, więc robię to wiele kroków, aby zaoszczędzić trochę pamięci w moim skrypcie PHP.

Ale jak mogę to zrobić, więc daje mi listę, która nie ma duplikatów w nazwach.

Na przykład zostanie zwrócony kod [1,"Michael Fox","2003-03-03,34,M,4545"], ale nie będzie to [2,"Michael Fox","1989-02-23,M,5633"]. Pole nazwy jest najważniejsze i musi być unikatowe na liście za każdym razem, gdy wybieram i musi być losowe.

Próbowałem z GROUP BY name, bu następnie oczekuje, że mam identyfikator i metadane w GROUP BY, a także w funkcji aggragate, ale nie chcę ich jakoś filtrowane.

Ktoś wie, jak pobrać wiele kolumn, ale robi tylko wyraźne w jednej kolumnie?

Odpowiedz

135

W tym wyraźny tylko na jednej (lub N), kolumnę (-y)

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

powoduje przywrócenie każdy z rzędów, zawierających nazwy. Jeśli chcesz kontrolować, które wiersze zostaną zwrócone trzeba zamówić:

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

zwróci pierwszy wiersz, gdy zamówione przez col1.

distinct on:

SELECT DISTINCT ON (wyrażenie [...]) utrzymuje tylko pierwszy wiersz każdego zestawu wierszy, gdzie podane wyrażenia oceniać na równi. Wyrażenia DISTINCT ON są interpretowane przy użyciu tych samych reguł, co w przypadku ORDER BY (patrz wyżej). Zauważ, że "pierwszy rząd" każdego zestawu jest nieprzewidywalny, chyba że ORDER BY służy do zapewnienia, że ​​żądany wiersz pojawi się jako pierwszy.

Wyrażenia DISTINCT ON muszą pasować do wyrażenia ORDER BY po lewej stronie. Klauzula ORDER BY zwykle zawiera dodatkowe wyrażenia, które określają pożądany priorytet wierszy w każdej grupie DISTINCT ON.

+0

Dobry połów przy zamawianiu. Nie uwzględniłem tego, ponieważ wspomnieli, że chcą losowego uporządkowania, ale ważne jest, aby o tym wspomnieć. –

+0

tak, kolejność jest również ważna, dziękuję. – NovumCoder

+0

Czy wymagane jest "zamówienie według nazwy"? Czy dałoby to inny wynik z 'order by col1'? –

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

Tylko słowo ostrzeżenia: może nie zwrócić wartości identyfikatora lub wartości metadanych, które należą "razem" –

+0

Hm, więc oznacza to, że sql nie jest poprawny? – NovumCoder

+0

@Novum No. Oznacza to, że cat pobiera wartość identyfikatora z jednego z wierszy Michaela, a metadane od innego, ponieważ został zapytany o maksima Michaela. –

12

Każdy wie, jak sprowadzić wiele kolumn, ale czy tylko wyraźna na jednej kolumnie?

Chcesz the DISTINCT ON clause.

Nie dostarczyłeś przykładowych danych ani kompletnego zapytania, więc nie mam nic do pokazania. Chcesz napisać coś w stylu:

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

Spowoduje to wyświetlenie nieprzewidywalnego (ale nie "losowego") zestawu wierszy. Jeśli chcesz, aby było to przewidywalne, dodaj odpowiedź na pytanie Clodaldo: ORDER BY. Jeśli chcesz, aby był naprawdę losowy, będziesz chciał ORDER BY random().

Powiązane problemy