Wie bekomme ich die Top 10 Werte in postgresql?

256

Ich habe eine einfache Frage:

Ich habe eine postgresqlDatenbank : Scores(score integer).

Wie würde ich die höchsten 10 Punkte am schnellsten erzielen?

AKTUALISIEREN:

Ich werde diese Abfrage mehrmals durchführen und strebe die schnellste Lösung an.

Joey Franklin
quelle
6
-1: Was hast du bisher gemacht? Warum ist das nicht gut genug? Was ist die Postgres-Version? Wo liegt explain analyze?
Mys

Antworten:

372

Hierfür können Sie limit verwenden

select *
from scores
order by score desc
limit 10

Wenn Leistung wichtig ist (wann nicht ;-), suchen Sie nach einem Index für die Punktzahl.


Ab Version 8.4 können Sie auch den Standard verwenden ( SQL: 2008 )fetch first

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

Wie @Raphvanns betonte, wird dies Ihnen first 10 rowsbuchstäblich das geben. Um doppelte Werte zu entfernen, müssen Sie distinctZeilen auswählen , z

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

SQL Fiddle

Olaf Dietsche
quelle
2
fetch first X rows onlyist die Antwort, nach der ich gesucht habe - danke aus der fernen Zukunft!
Mass Dot Net
36

Scheint, als würden Sie ORDER BYin DESCder Endreihenfolge mit der LIMIT- Klausel suchen :

SELECT
 *
FROM
  scores
ORDER BY score DESC
LIMIT 10

Dies kann natürlich SELECT *die Leistung ernsthaft beeinträchtigen. Verwenden Sie es daher mit Vorsicht.

Grzegorz Gierlik
quelle
3

Beachten Sie, dass Sie bei Verknüpfungen mit den Top-10-Werten nur die Top-10-Zeilen erhalten, nicht die Top-10- Werte mit den angegebenen Antworten. Beispiel: Wenn die Top 5-Werte 10, 11, 12, 13, 14, 15 sind, Ihre Daten jedoch 10, 10, 11, 12, 13, 14, 15 enthalten, erhalten Sie nur 10, 10, 11, 12, 13, 14 als Ihre Top 5 mit aLIMIT

Hier ist eine Lösung, die mehr als 10 Zeilen zurückgibt, wenn es Bindungen gibt, aber Sie erhalten alle Zeilen, in denen some_value_columnsich technisch gesehen die Top 10 befinden.

select
  *
from
  (select
     *,
     rank() over (order by some_value_column desc) as my_rank
  from mytable) subquery
where my_rank <= 10
Raphvanns
quelle
Von seiner Frage gibt es nur eine Spalte in der Tabelle. Warum also nicht "eine bestimmte Punktzahl aus der Punktzahlreihenfolge nach Punktzahl ab 10 auswählen"?
Derek
@Derek, guter Punkt. Dies wäre jedoch wahrscheinlich nicht der Fall in einer realen App, in der wir normalerweise versuchen, die Top-N von "etwas" zu identifizieren.
Raphvanns
Wahr. Ich konzentriere mich nur auf seine genaue Frage. Außerdem hatte ich viel Glück bei der Verwendung von limit in einer Unterabfrage wie Ihrer, z. B. "select * from table where value in (wähle einen bestimmten Wert aus der Tabellenreihenfolge nach value desc limit 10 aus)". Ich denke , das entspricht deiner. Ich bin mir nicht sicher, welche unserer Abfragen eine bessere Leistung erbringen würde. Dies hängt wahrscheinlich von der Tabellenstruktur und der Indizierung ab.
Derek
Nach Rang () fehlt ein Schlüsselwort OVER
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
quelle