2010-08-17 5 views
0

Je fais un travail de refactoring sur le code PHP/MySQL et suis tombé sur un problème intéressant, et pour le moment, je ne trouve pas de solution appropriée pour cela.MySQL Refactoring avec GROUP BY et HAVING

Je possède ce tableau:

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 
); 

Ce que je suis en train de faire est d'obtenir la dernière entrée de ligne pour chaque ID utilisateur distinct.

Actuellement, il est fait comme ceci:

SELECT DISTINCT userID 
FROM example 

puis avec boucle PHP I sur le résultat et exécuter cette requête pour chaque ID utilisateur distinct

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

J'ai essayé de combiner ces requêtes en une seule en utilisant:

GROUP BY userID 
HAVING MAX(timestamp) 

mais en vain.

Des suggestions?

Répondre

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) 

ou

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

les deux fonctionnent, bien que la deuxième requête soit beaucoup plus rapide! Bravo –

+0

Pas de soucis. Si vous pouvez avoir des liens sur userId, timestamp alors cette réponse ne traite pas actuellement de cette possibilité que fait Quassnoi. –

+0

hmm bien, techniquement il est toujours possible d'avoir plus d'une entrée, par utilisateur, par seconde. –

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 
     ) 

Cela fonctionne correctement même si vous avez des doublons sur timestamp.

Créez un index sur (userid, timestamp, id) pour que cela fonctionne rapidement.