2014-09-24 126 views
1

我正在尋找每個顯示「名稱」及其最新「分數」(按照時間順序倒序)的「學生」類型用戶返回一行。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 users.id, users.name, services.date, services.score 
FROM users 
JOIN services ON users.id = services.userId 
WHERE users.type='student' 
ORDER BY services.date DESC 

但是,這總是返回每個用戶表中的最後日期。

所以我決定嘗試從另一端是這樣處理的:

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 2014-09-24 10:50:25

+0

在這種情況下,只要返回一個,它並不重要。 – 2014-09-24 10:52:28

+0

@TraceyTurn:是的,因爲你的'日期'和'分數'不同步...你是否只是*任何*'分數'返回? – NoobEditor 2014-09-24 10:57:33

回答

1

嘗試:

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

完美,謝謝。 – 2014-09-24 11:25:22

0

您可以通過使用substring_index()/group_concat()招保證一行:

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; 

不使用group by,爲每個用戶只得到了一排另一種選擇是使用變量。或者,如果你知道的ID被按順序分配,使用的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';