2010-08-17 110 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)上創建一個索引,以便快速工作。