Na przykład chciałbym wybrać id z maksymalną datą grupy według kategorii, wynik to: 7, 2, 6
id category date
1 a 2013-01-01
2 b 2013-01-03
3 c 2013-01-02
4 a 2013-01-02
5 b 2013-01-02
6 c 2013-01-03
7 a 2013-01-03
8 b 2013-01-01
9 c 2013-01-01
Czy mogę wiedzieć, jak to zrobić w PostgreSQL?
sql
postgresql
greatest-n-per-group
user2412043
źródło
źródło
Odpowiedzi:
Jest to doskonały przypadek użycia dla
DISTINCT ON
(specyficzne rozszerzenie standardu PostgresDISTINCT
):SELECT DISTINCT ON (category) id -- , category, date -- add any other column (expression) from the same row FROM tbl ORDER BY category, "date" DESC;
Ostrożnie z malejącym porządkiem sortowania. Jeśli kolumna może mieć wartość NULL, możesz dodać
NULLS LAST
:DISTINCT ON
jest najprostszy i szybki. Szczegółowe wyjaśnienie w tej powiązanej odpowiedzi:W przypadku dużych stołów rozważ alternatywne podejście:
Optymalizacja wydajności dla wielu wierszy na
category
:źródło
Spróbuj tego:
SELECT t1.* FROM Table1 t1 JOIN ( SELECT category, MAX(date) AS MAXDATE FROM Table1 GROUP BY category ) t2 ON T1.category = t2.category AND t1.date = t2.MAXDATE
Zobacz to SQLFiddle
źródło
Innym podejściem jest użycie
first_value
funkcji okna: http://sqlfiddle.com/#!12/7a145/14SELECT DISTINCT first_value("id") OVER (PARTITION BY "category" ORDER BY "date" DESC) FROM Table1 ORDER BY 1;
... chociaż podejrzewam, że sugestia hims056 będzie zazwyczaj działać lepiej, gdy obecne są odpowiednie indeksy.
Trzecie rozwiązanie to:
SELECT id FROM ( SELECT id, row_number() OVER (PARTITION BY "category" ORDER BY "date" DESC) AS rownum FROM Table1 ) x WHERE rownum = 1;
źródło
WYBIERZ identyfikator Z tbl GRUPA WEDŁUG KOTÓW MAJĄCYCH MAX (data)
źródło