Как получить 10 лучших значений в postgresql?

257

У меня простой вопрос:

У меня есть postgresqlбаза данных: Scores(score integer).

Как бы я получил самые высокие 10 баллов быстрее?

ОБНОВИТЬ:

Я буду делать этот запрос несколько раз и стремлюсь к самому быстрому решению.

Джои Франклин
источник
6
-1: что ты на сегодня сделал? Почему этого недостаточно? Что такое версия Postgres? Где explain analyze?
МЫС

Ответы:

374

Для этого вы можете использовать лимит

select *
from scores
order by score desc
limit 10

Если производительность важна (когда это не так ;-) ищите индекс на счет.


Начиная с версии 8.4, вы также можете использовать стандарт ( SQL: 2008 )fetch first

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

Как указал @Raphvanns, это даст вам first 10 rowsбуквально. Чтобы удалить повторяющиеся значения, вы должны выбрать distinctстроки, например

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

SQL Fiddle

Олаф Дитче
источник
2
fetch first X rows onlyэто ответ, который я искал - спасибо из далекого будущего!
Mass Dot Net
36

Кажется, вы ищете ORDER BYв DESCконечном порядке с предложением LIMIT :

SELECT
 *
FROM
  scores
ORDER BY score DESC
LIMIT 10

Конечно, это SELECT *может серьезно повлиять на производительность, поэтому используйте его с осторожностью.

Гжегож Герлик
источник
3

Обратите внимание, что если есть связи в первых 10 значениях, вы получите только первые 10 строк, а не 10 лучших значений с предоставленными ответами. Пример: если верхние 5 значений 10, 11, 12, 13, 14, 15, но ваши данные содержат 10, 10, 11, 12, 13, 14, 15, вы получите только 10, 10, 11, 12, 13, 14 как ваш топ 5 сLIMIT

Вот решение, которое будет возвращать более 10 строк, если есть связи, но вы получите все строки, которые some_value_columnтехнически находятся в топ-10.

select
  *
from
  (select
     *,
     rank() over (order by some_value_column desc) as my_rank
  from mytable) subquery
where my_rank <= 10
Raphvanns
источник
От его вопроса в таблице только один столбец. Так почему бы не "выбрать отличную оценку из порядка оценок по пределу оценки 10"?
Дерек
@ Дерек, хорошая мысль. Хотя это, вероятно, не будет иметь место в приложении реального мира, где мы обычно ищем, чтобы определить верхнюю букву «чего-то».
Рафванны
Правда. Просто сосредоточиться на своем точном вопросе. Кроме того, мне повезло, используя лимит в подзапросе, подобном вашему, например, «выбрать * из таблицы, где значение в (выбрать отличное значение из порядка таблицы по значению desc limit 10)» Я думаю, что это эквивалентно вашему . Я не уверен, какой из наших запросов будет работать лучше, вероятно, это будет зависеть от структуры таблицы и индексации.
Дерек
Отсутствует ключевое слово 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
источник