我希望为“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
但是我意识到,如果日期相同,我最终会得到重复项,而且每个用户只能返回一行(并且双重分组不起作用)。
我认为我现在已经过度复杂了,所以我会非常感激生命线。
答案 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';