Bagaimana cara mendapatkan 10 nilai teratas di postgresql?

257

Saya punya pertanyaan sederhana:

Saya memiliki postgresqldatabase yang: Scores(score integer).

Bagaimana saya mendapatkan skor tertinggi 10 tercepat?

MEMPERBARUI:

Saya akan melakukan kueri ini beberapa kali dan mengincar solusi tercepat.

Joey Franklin
sumber
6
-1: apa yang telah kamu lakukan sejauh ini? Mengapa itu tidak cukup baik? Apa versi Postgres? Dimana explain analyze?
mys

Jawaban:

373

Untuk ini, Anda dapat menggunakan batas

select *
from scores
order by score desc
limit 10

Jika kinerja penting (padahal bukan ;-) cari indeks skor.


Mulai dengan versi 8.4, Anda juga dapat menggunakan standar ( SQL: 2008 )fetch first

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

Seperti yang ditunjukkan oleh @Raphvanns, ini akan memberi Anda arti first 10 rowssebenarnya. Untuk menghapus nilai duplikat, Anda harus memilih distinctbaris, misalnya

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

SQL Fiddle

Olaf Dietsche
sumber
2
fetch first X rows onlyadalah jawaban yang saya cari - terima kasih dari masa depan yang jauh!
Mass Dot Net
36

Sepertinya Anda mencari ORDER BYdi DESCberakhir pesanan dengan LIMIT klausa:

SELECT
 *
FROM
  scores
ORDER BY score DESC
LIMIT 10

Tentu saja SELECT *dapat memengaruhi kinerja secara serius, jadi gunakan dengan hati-hati.

Grzegorz Gierlik
sumber
3

Perhatikan bahwa jika ada ikatan dalam 10 nilai teratas, Anda hanya akan mendapatkan 10 baris teratas, bukan 10 nilai teratas dengan jawaban yang diberikan. Mis: jika 5 nilai teratas adalah 10, 11, 12, 13, 14, 15 tetapi data Anda berisi 10, 10, 11, 12, 13, 14, 15 Anda hanya akan mendapatkan 10, 10, 11, 12, 13, 14 sebagai top 5 Anda dengan aLIMIT

Berikut adalah solusi yang akan mengembalikan lebih dari 10 baris jika ada ikatan tetapi Anda akan mendapatkan semua baris di mana some_value_columnsecara teknis berada di atas 10.

select
  *
from
  (select
     *,
     rank() over (order by some_value_column desc) as my_rank
  from mytable) subquery
where my_rank <= 10
Raphvanns
sumber
Dari pertanyaannya hanya ada satu kolom di tabel. Jadi mengapa tidak "memilih skor berbeda dari skor Skor dengan batas skor desc skor 10"?
Derek
@ Derek, poin bagus. Meskipun itu mungkin tidak akan terjadi di aplikasi dunia nyata di mana kita biasanya mencari untuk mengidentifikasi N atas "sesuatu".
Raphvanns
Benar. Hanya fokus pada pertanyaannya. Juga, saya sudah beruntung menggunakan batas dalam subquery seperti milik Anda, misalnya "pilih * dari tabel di mana nilai dalam (pilih nilai yang berbeda dari urutan tabel dengan nilai desc batas 10)" Saya pikir itu setara dengan Anda. Saya tidak yakin yang mana dari pertanyaan kami akan berkinerja lebih baik, mungkin akan tergantung pada struktur tabel dan pengindeksan.
Derek
Ada kata kunci yang hilang OVER after rank ()
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
sumber