2011-09-03 38 views
3

的最后一个动作我有一个表是这样的:MySQL的:选择每个用户

ActionTime    UserID  Score 
2011-08-15 12:06:00  1    14 
2011-08-15 14:45:00  2    17 
2011-08-16 12:17:00  1    20 <== select this row 
2011-08-16 04:28:00  2    14 
2011-08-17 06:52:00  2    16 <== select this row 

我想了解每个用户在他们的最后一个动作的得分和ActionTime。 (如上所示)

我知道我能做到一个个像这样的:

SELECT * from MyTable WHERE UserID=? ORDER BY ActionTime DESC LIMIT 1 

但我们有数百种不同的用户名的(和它保持课程的增加)。这将导致大量的PHP到MySQL的通信,这是不可接受的。

我只是想知道是否有可能一次获得所有的行执行/通信?

回答

10

如果您为每个用户ID的最大ActionTime第一个查询,你可以使用它作为一个子查询,选择得分:

SELECT m.* 
FROM MyTable AS m 
INNER JOIN (
    SELECT MAX(i.ActionTime) ActionTime, i.UserID 
    FROM MyTable i 
    GROUP BY i.UserID 
) AS j ON (j.ActionTime = m.ActionTime AND j.UserID = m.UserID) 

有与上述SQL的一个问题 - 如果同一用户拥有更多比具有相同ActionTime的1行,您将获得该用户的多行。如果你决定要在这种情况下,最高的分数,你可以这样做:

SELECT m.ActionTime, m.UserID, MAX(m.Score) Score 
FROM MyTable AS m 
INNER JOIN (
    SELECT MAX(i.ActionTime) ActionTime, i.UserID 
    FROM MyTable i 
    GROUP BY i.UserID 
) AS j ON (j.ActionTime = m.ActionTime AND j.UserID = m.UserID) 
GROUP BY m.UserID 
+0

好极了!这正是我正在寻找的。 – LazNiko

-1

SELECT * FROM MyTable的集团通过用户ID ORDER BY ActionTime DESC

+2

ORDER BY应用于GROUP BY子句后的结果集 - 它不能更改结果集,只能重新排序,因此无法确保所选的ActionTime是最新的,或者选择的分数与它匹配。 – Gus

+0

你是对的。我的错。谢谢 – ZigZag