2014-09-24 8 views
1

"student"유형의 각 사용자에 대해 "이름"과 최신 "점수"를 역순으로 표시하는 한 행을 반환하려고합니다.mySql INNER JOIN, MAX & DISTINCT

나는 두 테이블 사용자 & 서비스

사용자 표

id name type 
---|-------|----- 
1 | Bob | student 
2 | Dave | student 
3 | Larry | student 
4 | Kevin | master 

서비스 테이블

id score userId date 
---|--------|-------|------------ 
1 | 14  | 1  | 2014-09-04 
2 | 99  | 3  | 2014-09-03 
3 | 53  | 2  | 2014-09-07 
4 | 21  | 1  | 2014-09-08 
5 | 79  | 2  | 2014-09-08 
6 | 43  | 3  | 2014-09-10 
7 | 72  | 3  | 2014-09-10 
8 | 66  | 2  | 2014-09-01 
9 | 43  | 3  | 2014-08-22 
10 | 26  | 1  | 2014-08-22 

원하는 결과를

id scores name date 
---|--------|-------|------------ 
3 | 43  | Larry | 2014-09-10 
1 | 21  | Bob | 2014-09-08 
2 | 79  | Dave | 2014-09-08 

ㅁ 나는 시도했다 :

그러나 항상 각 사용자에 대해 테이블의 마지막 날짜를 반환합니다.

그래서 나는 시도하고이 같은 다른 쪽 끝에서를 해결하기로 결정

SELECT servicesTemp.date, servicesTemp.score 
FROM services servicesTemp 
INNER JOIN 
    (SELECT userId, MAX(date) AS MaxExpDate 
    FROM services 
    GROUP BY clientId) servicesTempGrp 
ON servicesTemp.userId = servicesTempGrp.userId 
AND servicesTemp.MaxDate = servicesTempGrp.MaxDate 

그러나 날짜는 이제까지 동일하면 내가 중복으로 끝날 것이라는 점을 깨닫고 난 단지 당 하나 개의 행을 반환 할 수 있습니다 사용자 (및 이중 그룹화가 작동하지 않음).

저는 지금이 일이 복잡해 졌다고 생각합니다. 그래서 인생 선은 크게 감사 할 것입니다.

+1

당신이 래리의 점수로 (43) 및 (72) 사이에서 어떻게 선택합니까? – Arth

+0

이 경우에는 하나만 반환되는 한 실제로 중요하지 않습니다. –

+0

@ TraceyTurn : 그렇습니다. 왜냐하면 당신의'date'와'score's가 동기화되지 않았기 때문입니다. 당신은 * 어떤 *'score'가 리턴 될 것입니까? – NoobEditor

답변

1

시도 : 당신은 substring_index()/group_concat() 트릭을 사용하여 하나 개의 행을 보장 할 수

SELECT users.id, users.name, services.date, services.score 
FROM users 
JOIN services ON users.id = services.userId 
WHERE users.type='client' 
AND services.date = (SELECT MAX(date) from services where userID = users.id) 
ORDER BY services.date DESC 
+0

완벽한, 감사합니다. –

0

: group by를 사용하지 않고

SELECT u.id, u.name, max(s.date) as date, 
     substring_index(group_concat(s.score order by date desc), ',', 1) as score 
FROM users u JOIN 
    services s 
    ON u.id = s.userId 
WHERE u.type = 'client' 
GROUP BY u.id, u.name 
ORDER BY s.date DESC; 

, 사용자 당 하나 개의 행을 얻기위한 또 다른 옵션은 변수를 사용하는 것입니다 . 당신이 식별자가 할당되고 순차적으로 알고있는 경우 또는의 id 대신 date의 사용

SELECT u.id, u.name, s.date, s.score 
FROM users u INNER JOIN 
    services s 
    on u.userId = s.userId INNER JOIN 
    (SELECT userId, MAX(id) AS MaxId 
     FROM services 
     GROUP BY userId 
    ) smax 
    ON s.userId = smax.userId and s.Id = smax.MaxId 
WHERE u.type = 'client';