2010-08-17 80 views
0

我正在做一些关于PHP/MySQL代码的重构工作,并偶然发现了一个有趣的问题,截至目前,我找不到合适的解决方案。MySQL重构GROUP BY和HAVING

我有这个表:

CREATE TABLE example 
(
    id  INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    userID INT UNSIGNED NOT NULL, 
    timestamp INT UNSIGNED NOT NULL, 
    value  DECIMAL(10,2) NOT NULL 
); 

什么我试图做的是让每个用户ID鲜明的最新行条目。

目前,它的完成这样的:

SELECT DISTINCT userID 
FROM example 
用PHP我遍历结果

然后并运行此查询为每个不同的用户ID

SELECT * 
FROM example 
WHERE userID = %u 
ORDER BY timestamp DESC 
LIMIT 1 

我想这些查询合并为一个使用:

GROUP BY userID 
HAVING MAX(timestamp) 

但无济于事。

有什么建议吗?

回答

2
SELECT e.id, e.userId, e.timestamp, e.value 
FROM example e 
WHERE NOT EXISTS 
    (SELECT * FROM example e2 
    WHERE e.UserId = e2.UserId and e2.timestamp > e.timestamp) 

SELECT e.id, e.userId, e.timestamp, e.value 
FROM example e 
JOIN (
    SELECT userId, MAX(timestamp) AS timestamp 
    FROM example 
    GROUP BY userId 
) x on 
    e.userId = x.userId and e.timestamp = x.timestamp 
+0

这两个工作,虽然第二个查询运行速度快得多!欢呼声 – 2010-08-17 10:15:17

+0

不用担心。如果你可以在userId,timestamp上有联系,那么这个答案目前不能处理Quassnoi的可能性。 – 2010-08-17 10:18:08

+0

嗯,从技术上讲,每个用户每秒可以有多个条目。 – 2010-08-17 10:23:59

3
SELECT e.* 
FROM (
     SELECT DISTINCT userid 
     FROM example 
     ) eo 
JOIN example e 
ON  e.id = 
     (
     SELECT id 
     FROM example ei 
     WHERE ei.userid = eo.userid 
     ORDER BY 
       userid DESC, `timestamp` DESC, id DESC 
     LIMIT 1 
     ) 

这将正常工作,即使你有timestamp重复。

(userid, timestamp, id)上创建一个索引,以便快速工作。