2009-12-03 7 views
0

J'ai une table avec user_id et lap_time et je suis en cours d'exécution de la requête suivante:Commande et regroupement en php/MySQL

SELECT `Lap`.`id`, `Lap`.`user_id`, `Lap`.`lap_time` 
FROM `laps` AS `Lap` 
WHERE `Lap`.`lap_time` < 57370 
GROUP BY `Lap`.`user_id` 
ORDER BY `Lap`.`lap_time` ASC 

Je suis en train d'obtenir les tous les tours qui sont plus rapides que X mais seulement utilisateurs uniques.

La requête ci-dessus ne retourne pas le tour des utilisateurs, c'est comme si je devais commander le GROUP BY si cela avait du sens?

Les utilisateurs peuvent avoir beaucoup de tours, donc il peut y avoir 10 tours plus vite que X mais ils sont tous du même utilisateur, donc je veux juste le tour supérieur pour cet utilisateur. L'espoir qui a du sens et quelqu'un peut aider!

Répondre

0

Cette requête vous donnera le meilleur tour pour chaque user_id (où lap_time est inférieur à 57370) et le faire correspondre avec l'ID d'enregistrement correct. et en général, les jointures ont une performance un peu meilleure avec mysql qu'avec les sous-sélections.

select l2.id, 
     l1.user_id, 
     l1.lap_time 
    from lap l1 
    inner join lap l2 
    on l1.id = l2.id 
    where l1.lap_time < 57370 
    group by l1.user_id 
    having min(l1.lap_time); 
0

Je pense que vous devriez utiliser un SELECT COUNT (*) AS some_field, grouper par ce champ et utiliser MAX pour obtenir le résultat par utilisateur.

0

Lorsque vous traitez avec des situations similaires, j'ai ajouté une sous-requête pour assurer qu'il n'y a pas un temps plus rapide pour l'utilisateur:

WHERE Lap.lap_time < 57370 AND NOT EXISTS (select 1 from laps where laps.user_id = Lap.user_id and laps.lap_time < Lap.lap_time)

1

La requête que vous avez retournera chaque tour pour chaque utilisateur qui est inférieur à 57370. Si vous voulez seulement le meilleur tour de chaque utilisateur, il suffit d'ajouter un MIN autour du lap_time

SELECT `Lap`.`id`, `Lap`.`user_id`, min(`Lap`.`lap_time`) as `best_lap_time` 
FROM `laps` AS `Lap` 
WHERE `Lap`.`lap_time` < 57370 
GROUP BY `Lap`.`user_id` 

en outre, vous interrogez la mise en forme est assez o verkill. Aucune raison de créer un alias de table lorsqu'il n'y a qu'une seule table dans la requête. Sauf si vous avez copié-collé cela à partir d'un programme qui l'a généré pour vous.

EDIT

Désolé, vous avez raison - le temps min ne correspond pas toujours à l'ID. Cela devrait faire l'affaire

select l.id 
    , l.user_id 
    , (select min(lap_time) 
      from lap 
     where lap_time < 57370 
      and user_id = l.user_id 
     ) as best_lap_time 
group by l.user_id 
having best_lap_time is not null 
order by best_lap_time asc; 
+0

Merci pour cela, léger problème tho, l'ID qui est retourné n'est pas l'ID de la MIN_tour_durée ... en tout cas ça? – designvoid

+0

J'avais raison, même si cela retourne le temps au tour le plus bas pour cet utilisateur, le lap.id dans la rangée n'est PAS le lap.id du temps au tour le plus bas et j'en ai vraiment besoin. – designvoid