SQL-запрос для получения лучших “n” баллов из списка

StackOverflow https://stackoverflow.com/questions/37743

  •  09-06-2019
  •  | 
  •  

Вопрос

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

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

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.На самом деле я решил эту проблему, но я думаю, что есть другие способы получить результат...быстрее и эффективнее, чем у меня.

Это было полезно?

Решение

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

select * from users where points in
(select distinct top 3 points from users 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

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

Как насчет:

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

Не уверен, что "с галстуками" работает на любом другом сервере SQL.

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

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

На самом деле модификация 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

@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

@Роб#37760:

select top N points from users order by points desc

Этот запрос выберет только 3 строки, если N равно 3, см. Вопрос."Top 3" должен возвращать 5 строк.

@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 и не были протестированы.

@Matt Hamilton

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

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

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

выберите * из списка пользователей по количеству пунктов, ограниченных 0,5

это даст 5 лучших очков

Попробуйте это

select top N points from users order by points desc
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top