2013-01-14 3 views
1

예제를 읽었지만 예제로는 작동하지 않습니다.그룹에 대한 MySQL 레코드 제한

'pid'와 'name'열이있는 'player'테이블과 'pid', 'points'열이있는 'card'테이블이 있습니다.

플레이어 기록에는 여러 개의 카드 기록이 있습니다.

플레이어 당 상위 5 개 레코드를 쿼리하려면 어떻게해야합니까?

이 쿼리는 필요한 항목을 반환하지만 이름 당 5 개의 레코드를 제한하지 않습니다.

SELECT p.pid, p.name, c.points as lp 
FROM player as p, card as c 
WHERE p.pid=c.pid 
ORDER BY p.name, lp DESC 
+0

순위를 지정하려면 임시 변수를 사용해야합니다. 명시 적으로'JOIN'을 사용하여 연습하는 것이 좋습니다. – Kermit

답변

1

MySQL이 지정된 결과 집합을 반환하는 데 필요한 "분석"형 기능을 지원하지 않습니다를 참조하십시오. MySQL "사용자 변수"를 사용하여 함수를 에뮬레이트 할 수 있습니다.

SELECT IF(@prev_name = p.name,@n:[email protected]+1,@n:=1) AS seq 
    , @prev_name := p.name AS name 
    , c.points as lp 
    FROM player as p 
    JOIN card as c 
    ON c.pid = p.pid 
    JOIN (SELECT @n := 0, @prev_name := NULL) i 
HAVING seq <= 5 
ORDER BY p.name, lp DESC 

이 문에서 나온 결과 집합은 "seq"라는 추가 열을 반환한다는 점에서 원래 문과 다릅니다. 이 열은 1,2,3 등의 값을 반환합니다. 이것은 특정 p.name에 대한 "첫 번째", "두 번째", "세 번째"등의 행인지 여부를 나타냅니다.

이 계산식은 기본적으로 현재 행의 p.name 값이 이전 행의 값과 일치하는지 여부를 확인하는 데 사용됩니다. 일치하면 1을 더합니다. 일치하지 않으면 0으로 재설정됩니다.

쿼리는 실제로 각 p.name에 대한 모든 행에 대한 결과 집합을 생성합니다. HAVING 절은 실제로 클라이언트에 리턴되는 행을 제한합니다.

2

각 사용자에 순위를 할당하는 변수를 사용할 수 있습니다 :

select pid, name, lp 
from 
(
    SELECT pid, 
     name, 
     points as lp, 
     @prev := @curr, 
     @curr := name, 
     @rank := IF(@prev = @curr, @rank+1, 1) AS rank 
    FROM 
    (
     select p.pid, name, points 
     FROM player as p 
     INNER JOIN card as c 
      ON p.pid=c.pid 
    ) src, (SELECT @curr := null, @prev := null, @rank := 1) r 
    ORDER BY name, points desc 
) src 
where rank <= 5 
order by name, lp DESC; 

SQL Fiddle with Demo

관련 문제