2010-07-20 9 views
1

J'ai une table avec 4 colonnes: place_id, username, counter, last_checkinavec une requête MySQL, la sélection d'un élément maximum

J'écris un système basé sur l'enregistrement et je suis en train d'obtenir un requête qui me donnera le "maire" de chaque lieu. Le maire est celui avec la plupart des check-ins, et s'il y a plus de 1 que le minimum last_checkin gagne.

Par exemple, si j'ai:

place_id, username, counter, last_checkin 
123,  tom,  3 ,  13/4/10 
123,  jill,  3,  14/4/10 
365,  bob,  2,  15/4/10 
365,  alice,  1,  13/4/10 

Je veux que le résultat soit:

123, tom 
365, bob 

Je l'utilise dans le code PHP


Voici la données de test:

CREATE TABLE `my_table` (`place_id` int(11), `username` varchar(50), `counter` int(11), `last_checkin` date); 
INSERT INTO `my_table` VALUES (123,'tom',3,'2010-04-13'),(123,'jill',3,'2010-04-14'),(365,'bob',2,'2010-04-15'),(365,'alice',1,'2010-04-13'); 
+1

Cela ressemble à la copie la plus flagrante de [foursquare] (http://foursquare.com/) J'ai déjà entendu parler de :) –

+0

quoi de neuf? haha je plaisante. évidemment j'ai utilisé des termes de foursquare pour rendre la question facile à comprendre :) – joe

Répondre

-2
$data = query("SELECT max(counter) counter,username FROM table GROUP By place_id ORDER By last_checkin DESC"); 
+0

Pourquoi le max (place_id)? En raison de max (compteur)? – fabrik

+0

une petite correction $ data = query ("SELECT place_id, nom d'utilisateur FROM table GROUP par MAX (compteur) ORDER By last_checkin DESC"); –

+0

désolé, j'ai fait une erreur et je l'ai réparé. Happens :) –

2

Que diriez-vous ..

SELECT 
    place_id, 
    (SELECT username 
     FROM my_table MT2 
     WHERE MT2.place_id = MT1.place_id 
     ORDER BY counter DESC, last_checkin ASC 
     LIMIT 1) AS mayor 
    FROM my_table MT1 
    GROUP BY place_id; 

Edité comme Déraison suggère d'avoir un ordre croissant pour last_checkin.

+1

last_checking devrait être ascendant, citation: 's'il y a plus de 1 que le minimum last_checkin gagne' – Unreason

+0

Oops. Tu as plutot raison. Je vais modifier et corriger. –

+0

OMG qui a fonctionné! (avec correction d'Unreason) Merci! – joe

2

La requête corrélée de Brian est quelque chose que j'écrirais. Cependant, je trouve ce different take et il pourrait fonctionner différemment selon les données

SELECT 
    mt1.place_id, 
    mt1.username 
FROM 
    my_table mt1 LEFT JOIN my_table mt2 
     ON mt1.place_id = mt2.place_id AND 
      (mt1.counter < mt2.counter OR 
      (mt1.counter = mt2.counter AND mt1.last_checkin > mt2.last_checkin) 
      ) 
WHERE 
    mt2.place_id IS NULL 

qui utilise rejoindre gauche pour obtenir au début des enregistrements selon certaines conditions.

+0

J'ai toujours été subquilien, car je trouve que les jointures me font mal à la tête. Mais votre solution est également correcte, et je soupçonne que les adhérents sont majoritaires sur ce site. Je ne pense pas qu'il y aura de différence de performances car l'optimiseur de requêtes peut réécrire des sous-requêtes en tant que jointures s'il le juge approprié. Faites ce que vous trouvez le plus facile. –

+0

En fait, je crois que dans ce cas, la sous-requête fonctionnerait plus vite sur certains jeux de données 'normaux' et que mysql pourrait être confus sur la jointure compliquée et qu'elle ne saurait pas la réécrire comme sous-requête.Cependant, j'ai aimé le principe (était frais pour moi) et je ne suis ni subqueric ni joinists, mais pro choix :) ainsi j'ai offert une solution différente. – Unreason