2010-03-28 5 views
3

점수 및 기타 정보 (예 : 점수 또는 시간 등)를 사용자가 저장하는 표가 있습니다. 나는 각 사용자의 개인 최고 점수를 발견 MySQL의 쿼리를 원하고 그것을 노트와 시간을 연관된 등사용자 최대 점수 및 관련 세부 정보 찾기

내가 사용하려고이 같은 것입니다 무엇을

:에 의해

SELECT *, MAX (점수) 테이블 그룹에서 (사용자)

이 문제는 해당 쿼리 [MAX (점수)]에서 사용자 개인 최고를 추가 할 수 있지만 반환 된 메모와 시간 등은 최대 점수와 관련이 없지만 다른 점수는 특히 *에 포함 된 것). 원하는 것을 선택하는 쿼리를 작성할 수있는 방법이 있습니까? 아니면 PhP에서 수동으로해야합니까?

+0

사용자가 두 개의 동등한 점수를 갖는 경우 최대, 당신은 둘 다 반환하거나 그들 중 하나를 원하십니까? 후자라면, 어느 쪽인가? –

답변

1

를 사용하는 것보다 필드를 지정하는 것이 좋습니다 다음과 같이 설명했다. 다음으로 시작합니다 :

SELECT t.* FROM table t; 

...이 자체로 테이블의 모든 내용이 분명히 나열됩니다. 목표는 특정 사용자의 최대 점수를 나타내는 행만 유지하는 것입니다. 우리는 아래의 데이터가 있다면 따라서 :

+------------------------+ 
| user | score | notes | 
+------+-------+---------+ 
| 1 | 10 | note a | 
| 1 | 15 | note b |  
| 1 | 20 | note c | 
| 2 |  8 | note d | 
| 2 | 12 | note e | 
| 2 |  5 | note f | 
+------+-------+---------+ 

... 우리는 단지 "노트 C"와 "참고 전자"행을 유지하고 싶었을 것이다.

우리가 유지하려는 행을 찾으려면, 우리는 간단하게 사용할 수 있습니다 : 당신이 이미 발견했다, 당신은하지 않기 때문에 우리는 메모를 얻을 수

SELECT MAX(score), user FROM table GROUP BY user; 

참고, 위의 쿼리에서 속성 MAX()과 같거나 GROUP BY 절의 일부가 아닌 aggregate function으로 집계되지 않은 필드의 예상 결과 더이 주제에 대한 독서를 들어, 확인 할 수 있습니다 :

이제 우리는 두 번째 일치하는 첫 번째 쿼리에서 행을 계속해야합니다 질문. 우리는 INNER JOIN하여이 작업을 수행 할 수 있습니다

... 
JOIN  (SELECT MAX(score) as max_score, 
        user 
      FROM  table 
      GROUP BY user) sub_t ON (sub_t.user = t.user AND 
            sub_t.max_score = t.score); 

서브 쿼리 이름 sub_t이 부여됩니다. 개인 최고 점수를 가진 모든 사용자의 집합입니다. JOINON 절은 관련 필드에 제한을 적용합니다. 이 하위 쿼리의 일부인 행만 유지하려고한다는 것을 기억하십시오.

+0

대단히 고맙습니다. :) 이 하위 쿼리 비즈니스에서 어떤 일이 일어나고 있는지 또는 자습서 나 다른 것을 가르쳐 줄 수있는 기회가 있습니까? 나는 전에 이것을 본 적이 없다. 그렇지 않다면, 고맙습니다. 그리고 저는 이것을 아침에 찾아 낼 것입니다! – VolatileStorm

+0

도움이 되니 기쁩니다. 어떤 점을 가지고 대답을 수정하겠습니다. –

+0

이 방법은 동일하지만 동일한 점수를 두 번 이상받는다면 여러 결과를 반환 할 수 있습니다. –

1
SELECT * 
FROM table t 
ORDER BY t.score DESC 
GROUP BY t.user 
LIMIT 1 

사이드 참고 :

SELECT t.*, 
     sub_t.max_score 
FROM  table t 
JOIN  (SELECT MAX(score) as max_score, 
        user 
      FROM  table 
      GROUP BY user) sub_t ON (sub_t.user = t.user AND 
            sub_t.max_score = t.score); 

위의 쿼리가 될 수 있습니다 다음과 같은 예에서와 같이 하위 쿼리에 가입 할 수 있습니다 SELECT *

+0

나는 이것이 그가 찾고있는 것이라고 생각하지 않는다. 각 사용자에 대해 행을 원합니다. –

1

동일한 최대 점수로 두 번 이상 득점 한 경우에도 플레이어 당 하나의 결과 만 원한다고 가정합니다.또한 각 플레이어가 처음 반복 할 때 자신의 성적이 최상이라고 생각한다고 가정합니다.

몇 가지 방법이 있습니다.

SELECT T3.* FROM table1 AS T3 
JOIN (
    SELECT T1.user, T1.score, MIN(scoredate) AS scoredate 
    FROM table1 AS T1 
    JOIN (SELECT user, MAX(score) AS score FROM table1 GROUP BY user) AS T2 
    ON T1.user = T2.user AND T1.score = T2.score 
    GROUP BY T1.user 
) AS T4 
ON T3.user = T4.user AND T3.score = T4.score AND T3.scoredate = T4.scoredate 

결과 : 내가 사용

1, '2010-01-01 17:00:00', 50, 'Much better' 
2, '2010-01-01 14:00:00', 100, 'Perfect score' 

테스트 데이터를 테스트하려면 :

여기
SELECT user, scoredate, score, notes FROM (
    SELECT *, @prev <> user AS is_best, @prev := user 
    FROM table1, (SELECT @prev := -1) AS vars 
    ORDER BY user, score DESC, scoredate 
) AS T1 
WHERE is_best 

은 일반 SQL을 사용하는 일반적인 방법 : 다음은 MySQL의 특정 방법이다

CREATE TABLE table1 (user INT NOT NULL, scoredate DATETIME NOT NULL, score INT NOT NULL, notes NVARCHAR(100) NOT NULL); 
INSERT INTO table1 (user, scoredate, score, notes) VALUES 
(1, '2010-01-01 12:00:00', 10, 'First attempt'), 
(1, '2010-01-01 17:00:00', 50, 'Much better'), 
(1, '2010-01-01 22:00:00', 30, 'Time for bed'), 
(2, '2010-01-01 14:00:00', 100, 'Perfect score'), 
(2, '2010-01-01 16:00:00', 100, 'This is too easy');