Jak zdobyć 10 najlepszych wartości w Postgresql?

256

Mam proste pytanie:

Mam postgresqlbazę danych: Scores(score integer).

Jak uzyskać najwyższe 10 punktów najszybciej?

AKTUALIZACJA:

Zrobię to zapytanie wiele razy i dążę do najszybszego rozwiązania.

Joey Franklin
źródło
6
-1: co zrobiłeś do tej pory? Dlaczego to nie wystarczy? Jaka jest wersja Postgres? Gdzie jest explain analyze?
mys

Odpowiedzi:

372

Do tego możesz użyć limitu

select *
from scores
order by score desc
limit 10

Jeśli wydajność jest ważna (kiedy nie jest ;-) poszukaj indeksu wyniku.


Począwszy od wersji 8.4, możesz także używać standardu ( SQL: 2008 )fetch first

select *
from scores
order by score desc
fetch first 10 rows only

Jak wskazał @Raphvanns, da ci to first 10 rowsdosłownie. Aby usunąć zduplikowane wartości, musisz wybrać distinctwiersze, np

select distinct *
from scores
order by score desc
fetch first 10 rows only

SQL Fiddle

Olaf Dietsche
źródło
2
fetch first X rows onlyto odpowiedź, której szukałem - dziękuję z dalekiej przyszłości!
Mass Dot Net
35

Wygląda na to, że szukasz ORDER BYw DESCkońcowej kolejności z klauzulą LIMIT :

SELECT
 *
FROM
  scores
ORDER BY score DESC
LIMIT 10

Oczywiście SELECT *może to poważnie wpłynąć na wydajność, więc używaj go ostrożnie.

Grzegorz Gierlik
źródło
3

Zauważ, że jeśli w najlepszych 10 wartościach są remisy, otrzymasz tylko 10 najlepszych wierszy, a nie 10 najlepszych wartości z podanymi odpowiedziami. Np .: jeśli 5 najlepszych wartości to 10, 11, 12, 13, 14, 15, ale twoje dane zawierają 10, 10, 11, 12, 13, 14, 15, otrzymasz tylko 10, 10, 11, 12, 13, 14 jako twoja pierwsza piątka zLIMIT

Oto rozwiązanie, które zwróci więcej niż 10 rzędów, jeśli są remisy, ale dostaniesz wszystkie wiersze, które some_value_columntechnicznie znajdują się w pierwszej dziesiątce.

select
  *
from
  (select
     *,
     rank() over (order by some_value_column desc) as my_rank
  from mytable) subquery
where my_rank <= 10
Raphvanns
źródło
Z jego pytania wynika tylko jedna kolumna w tabeli. Dlaczego więc nie „wybrać odrębnego wyniku z kolejności wyników według oceny desc limit 10”?
Derek
@Derek, dobra uwaga. Chociaż prawdopodobnie nie miałoby to miejsca w aplikacji z prawdziwego świata, w której zwykle szukamy zidentyfikowania górnej N „czegoś”.
Raphvanns
Prawdziwe. Koncentrując się na jego dokładnym pytaniu. Miałem też szczęście, używając limitu w podzapytaniu takim jak twoje, np. „Wybierz * z tabeli, w której wartość jest (wybierz odrębną wartość z kolejności tabeli według wartości desc limit 10)” Myślę , że jest to równoważne z twoim. Nie jestem pewien, które z naszych zapytań działałoby lepiej, prawdopodobnie zależałoby to od struktury tabeli i indeksowania.
Derek
Brakuje słowa kluczowego OVER po rankingu ()
Tiago Alcobia
2
(SELECT <some columns>
FROM mytable
<maybe some joins here>
WHERE <various conditions>
ORDER BY date DESC
LIMIT 10)

UNION ALL

(SELECT <some columns>
FROM mytable
<maybe some joins here>
WHERE <various conditions>
ORDER BY date ASC    
LIMIT 10)
kashif
źródło