SQL-запрос для получения первых "n" оценок из списка

Я хотел бы найти различные способы решения реальной жизненной проблемы: представьте, что у меня есть конкурс или игра, во время которой пользователи набирают очки. Вы должны создать запрос, чтобы показать список пользователей с лучшими оценками "n".

Я привожу пример, чтобы прояснить ситуацию. Допустим, это таблица Users с заработанными баллами:

UserId - Points
1      - 100
2      -  75
3      -  50
4      -  50
5      -  50
6      -  25

Если я хочу получить 3 лучших результата, результат будет следующим:

UserId - Points
1      - 100
2      -  75
3      -  50
4      -  50
5      -  50

Это может быть реализовано в виде или в хранимой процедуре по вашему желанию. Моя целевая база данных - это Sql Server. На самом деле я решил это, но я думаю, что есть другой способ получить результат ... быстрее или эффективнее, чем мой.

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
7
0
19 073
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Ответ принят как подходящий

Не проверено, но должно работать:

select * from users where points in
(select distinct top 3 points from users order by points desc)

@bosnic, я не думаю, что это сработает, как просили, я не так хорошо знаком с MS SQL, но я ожидал, что он вернет только 3 строки и проигнорирует тот факт, что 3 пользователя привязаны к 3-му месту.

Примерно так должно работать:

select userid, points 
   from scores 
   where points in (select top 3 points 
                       from scores 
                       order by points desc) 
   order by points desc

@Espo благодарит за проверку реальности - добавлен подвыбор, чтобы исправить это.

Думаю, самый простой ответ:

select userid, points from users
where points in (select distinct top N points from users order by points desc) 

Если вы хотите поместить это в сохраненную процедуру, которая принимает N в качестве параметра, вам придется либо прочитать SQL в переменную, а затем выполнить его, либо выполнить трюк с подсчетом строк:

declare @SQL nvarchar(2000)
set @SQL = "select userID, points from users "
set @SQL = @SQL + " where points in (select distinct top " + @N
set @SQL = @SQL + " points from users order by points desc)"

execute @SQL

или же

SELECT  UserID, Points
FROM     (SELECT  ROW_NUMBER() OVER (ORDER BY points DESC)
         AS Row, UserID, Points FROM Users)
        AS usersWithPoints
WHERE  Row between 0 and @N

Оба примера предполагают использование SQL Server и не тестировались.

@ Роб # 37760:

select top N points from users order by points desc

Этот запрос выберет только 3 строки, если N равно 3, см. Вопрос. «Верхняя 3» должна вернуть 5 строк.

Как насчет:

select top 3 with ties points 
from scores
order by points desc

Не уверен, что "со связями" работает на чем-нибудь другом SQL Server.

В SQL Server 2005 и более поздних версиях вы можете передать "верхнее" число как параметр типа int:

select top (@n) with ties points 
from scores
order by points desc

Вот тот, который работает - я не знаю, эффективнее ли он, и это SQL Server 2005+.

with scores as (
    select 1 userid, 100 points
    union select 2, 75
    union select 3, 50
    union select 4, 50
    union select 5, 50
    union select 6, 25
),
results as (
    select userid, points, RANK() over (order by points desc) as ranking 
    from scores
)
select userid, points, ranking
from results
where ranking <= 3

Очевидно, что первое «с» - это установка значений, так что вы можете протестировать второе с помощью и окончательный выбор работы - вы можете начать с «с результатами как ...», если бы вы выполняли запрос к существующей таблице.

У меня аналогичная проблема, и я пытался использовать MAX, а затем я прочитал ваш ответ и вспомнил DENSE_RANK. Сэкономил мне много времени.

DataGirl 22.06.2012 00:49

@ Мэтт Гамильтон

Ваш ответ работает с приведенным выше примером, но не будет работать, если набор данных будет 100, 75, 75, 50, 50 (где он вернет только 3 строки). TOP WITH TIES включает только связи последней возвращенной строки ...

Crucible получил это (при условии, что SQL 2005 - это вариант).

На самом деле модификация WHERE IN с использованием INNER JOIN будет намного быстрее.

SELECT 
   userid, points 
FROM users u
INNER JOIN 
(
   SELECT DISTINCT TOP N 
      points 
   FROM users 
   ORDER BY points DESC
) AS p ON p.points = u.points

Попробуй это

select top N points from users order by points desc

Эй, я нашел все остальные ответы немного длинными и неэффективными Мой ответ был бы таким:

select * from users order by points desc limit 0,5

это отобразит верхние 5 баллов

Другие вопросы по теме