2010-04-17 7 views
1

Possible en double:
Retrieving the last record in each groupLa meilleure façon de construire cette requête?

J'ai deux tables mis en place similaire à celle (simplifiée pour la recherche):

actions-

id - user_id - action - time 

utilisateurs -

id - name 

Je souhaite afficher la dernière action pour chaque utilisateur. Je n'ai aucune idée de comment s'y prendre.

Je ne suis pas génial avec SQL, mais d'après ce que j'ai recherché, il devrait ressembler à ceci. pas sûr cependant.

SELECT `users`.`name`, * 
FROM users, actions 
JOIN < not sure what to put here > 
ORDER BY `actions`.`time` DESC 
< only one per user_id > 

Toute aide serait appréciée.

+0

Eh bien, une réponse a déjà été acceptée, mais vous avez une bonne conférence là-bas si vous voulez: http: // stackoverflow.com/questions/1907534/retrieve-2-derniers-posts-pour-chaque-catégorie – Savageman

Répondre

1
SELECT * FROM users JOIN actions ON actions.id=(SELECT id FROM actions WHERE user_id=users.id ORDER BY time DESC LIMIT 1); 
+0

Une raison spécifique pour laquelle vous utilisez une sous-requête? Ça a l'air un peu compliqué pour le travail à faire, non? –

+2

Principalement l'ignorance SQL, j'utilise des sous-requêtes tout le temps quand je ne devrais probablement pas :). S'il y a un meilleur moyen, vous devriez le poster comme une réponse séparée –

+0

Eh bien, honnêtement, je ne suis pas non plus gourou SQL ... Je pensais que vous pourriez avoir une raison géniale de savoir pourquoi vous le feriez de cette façon. ;-) –

0

select u.name, a.action, a.time
de l'utilisateur u, l'action d'un
où u.id = a.user_id
et a.time en (choisir max (heure) de l'action où user_id = u.user_id groupe par user_id)



note non testé - mais cela devrait être le modèle

1

vous devez faire un maximum groupwise - s'il vous plaît se référer à des exemples ici http://jan.kneschke.de/projects/mysql/groupwise-max/

est ici un exemple que je l'ai fait pour Somone autre qui est semblable à vos besoins:

http://pastie.org/925108

select 
u.user_id, 
u.username, 
latest.comment_id 
from 
users u 
left outer join 
(
    select 
    max(comment_id) as comment_id, 
    user_id 
    from 
    user_comment 
    group by 
    user_id 
) latest on u.user_id = latest.user_id; 
0
DECLARE @Table (ID Int, User_ID, Time DateTime) 

-- This gets the latest entry for each user 
INSERT INTO @Table (ID, User_ID, Time) 
SELECT ID, User_ID, MAX(TIME) 
FROM actions z 
INNER JOIN users x on x.ID = z.ID 
GROUP BY z. userID 

-- Join to get resulting action 
SELECT z.user_ID, z.Action 
FROM actions z 
INNER JOIN @Table x on x.ID = z.ID 
0

C'est le plus grand-n-par groupe problème qui revient souvent sur la pile Débordement. Suivez le tag pour des dizaines d'autres messages sur ce problème.

Voici comment faire dans MySQL donné votre schéma sans sous-requêtes et pas GROUP BY:

SELECT u.*, a1.* 
FROM users u JOIN actions a1 ON (u.id = a1.user_id) 
LEFT OUTER JOIN actions a2 ON (u.id = a2.user_id AND a1.time < a2.time) 
WHERE a2.id IS NULL; 

En d'autres termes, montrer à l'utilisateur avec son action telle que si nous cherchons une autre action avec le même utilisateur et plus tard, nous n'en trouvons aucun.

0

Il me semble que ce qui suit sera des œuvres

WITH GetMaxTimePerUser (user_id, time) (
    SELECT user_id, MAX(time) 
    FROM actions 
    GROUP BY user_id 
) 
SELECT u.name, a.action, amax.time 
FROM actions AS a 
    INNER JOIN users AS u ON u.id=a.user_id 
    INNER JOIN GetMaxTimePerUser AS u_maxtime ON u_maxtime.user_id=u.id 
WHERE a.time=u_maxtime.time 

Utilisation du jeu temporaire nommé result (expression de table commune ou CTE) sans sous-requêtes et OUTER JOIN est la meilleure façon ouverte pour l'optimisation des requêtes. (CTE est quelque chose comme un VIEW mais existant seulement virtuel ou inline)

Questions connexes