mySql INNER JOIN,MAX&不同

时间:2014-09-24 10:41:59

标签: mysql sql join distinct

我希望为“student”类型的每个用户返回一行,显示他们的“姓名”和他们最新的“得分”(按时间倒序排列)。

我有两个表用户&服务

用户表

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

但是我意识到,如果日期相同,我最终会得到重复项,而且每个用户只能返回一行(并且双重分组不起作用)。

我认为我现在已经过度复杂了,所以我会非常感激生命线。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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';