SQL-запрос для получения лучших «n» баллов из списка - PullRequest
6 голосов
/ 01 сентября 2008

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

Ответы [ 11 ]

10 голосов
/ 01 сентября 2008

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

select * from users where points in
(select distinct top 3 points from users order by points desc)
4 голосов
/ 01 сентября 2008

Вот тот, который работает - я не знаю, является ли он более эффективным, и это 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

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

1 голос
/ 18 сентября 2008

На самом деле модификация 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
1 голос
/ 01 сентября 2008

Как насчет:

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
0 голосов
/ 01 ноября 2013

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

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

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

0 голосов
/ 19 сентября 2008

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

select top N points from users order by points desc
0 голосов
/ 01 сентября 2008

Crucible получил его (при условии, что SQL 2005 является опцией).

0 голосов
/ 01 сентября 2008

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

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

0 голосов
/ 01 сентября 2008

@ Rob # 37760:

select top N points from users order by points desc

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

0 голосов
/ 01 сентября 2008

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

...