문제

나는 내가 겪고 있는 실제 생활 문제를 해결하기 위한 다양한 방법을 찾고 싶습니다.사용자가 포인트를 모으는 콘테스트나 게임을 상상해 보세요.최고의 "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

이는 원하는 대로 뷰나 저장 프로시저에서 실현될 수 있습니다.내 대상 DB는 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

분명히 첫 번째 "with"는 값을 설정하는 것이므로 두 번째를 테스트하고 최종 선택 작업을 수행할 수 있습니다. 기존 테이블에 대해 쿼리하는 경우 "결과를 다음과 같이..."에서 시작할 수 있습니다.

어떻습니까:

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

"연결 포함"이 SQL Server 이외의 다른 항목에서도 작동하는지 확실하지 않습니다.

SQL Server 2005 이상에서는 "top" 숫자를 int 매개변수로 전달할 수 있습니다.

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

실제로 INNER JOIN을 활용하면 WHERE IN을 수정하는 것이 훨씬 빠릅니다.

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

이 쿼리는 N이 3인 경우 3개의 행만 선택합니다. 질문을 참조하세요."상위 3개"는 5개의 행을 반환해야 합니다.

@Espo 현실 확인에 감사드립니다. 이를 수정하기 위해 하위 선택을 추가했습니다.

가장 쉬운 대응은 다음과 같습니다.

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

N을 매개변수로 사용하는 저장된 proc에 이를 넣으려면 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를 가정하고 테스트되지 않았습니다.

@맷 해밀턴

귀하의 답변은 위의 예에서는 작동하지만 데이터 세트가 100, 75, 75, 50, 50(3개의 행만 반환하는 경우)인 경우에는 작동하지 않습니다.TOP WITH TIES에는 반환된 마지막 행의 동점만 포함됩니다.

Crucible이 이를 얻었습니다(SQL 2005가 옵션이라고 가정).

이봐, 나는 다른 모든 대답이 조금 길고 비효율적이라는 것을 알았다. 내 대답은 다음과 같습니다.

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

그러면 상위 5개 포인트가 렌더링됩니다.

이 시도

select top N points from users order by points desc
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top