Version complète: sur le forum Webmaster Hub : Épurer les résultats suite à un LEFT JOIN
Webmaster Hub > Création et exploitation de Sites Internet > Les langages du Net > SQL
aspeum
Voici ma situation :

- J'ai deux tables, CONTACT et COMMANDE.
- Un contact peut avoir zéro, une ou plusieurs commandes.
- Je cherche à effectuer une requête MySQL qui me liste tous les contacts avec la date de leur dernière commande.

Ma requête de départ serait donc :
CODE
SELECT contact.nom, commande.date FROM contact LEFT JOIN commande ON contact.id_contact = commande.id_contact

Le problème, c'est qu'elle m'affiche plus que je ne le souhaite. Exemple :
CODE
Jean => 2006-01-28
Jean => 2007-05-26
Thomas => 2008-01-05
Pierre => NULL
Antoine => 2005-11-24
Antoine => 2004-08-30

Or, je ne voudrais que :
CODE
Jean => 2007-05-26
Thomas => 2008-01-05
Pierre => NULL
Antoine => 2005-11-24


Est-ce que quelqu'un saurait me dire comment faire ? Je précise que je sais comment contourner cette solution en passant par du PHP, mais que uniquement via une requête que j'aimerais trouver la solution.

Merci d'avance pour toute aide.
Kioob
Hello,

"GROUP BY" correspond justement à ça : un group by sur l'idcontact, et un max(commande.date) et c'est réglé.
aspeum
Je n'utilisais GROUP BY qu'avec un COUNT, je n'avais pensé à l'associer à un MAX...

Merci infiniment pour ta réponse ; sauf erreur de ma part, ça résout mon problème.

Je vais le tester dans mon cas réel (qui est bien plus compliqué que la version simplifiée que j'ai exposé ci-dessus), pour vérifier.
petit-ourson
Tant qu'il a pas besoin de récupérer l'id de la commande, un group by comme cela suffira effectivement.
aspeum
Pourquoi ? Que se passe-t-il si je cherche aussi à récupérer l'id de la commande ? La requête ne va-t-elle pas sortir l'id qui correspond à la commande ayant la date la plus récente ?

Et si ça bloque, y aurait-il une autre solution ?
Kioob
A moins de faire un "max(id_command)" et croiser les doigts pour que les numéros de commande soient dans l'ordre chronologique, non tu ne peux pas directement obtenir l'id correspondant à la commande la plus récente.
Tu es obligé de passer par une requête imbriquée (ou table temporaire, ou encore une vue).
aspeum
OK, donc si je demande d'aller chercher l'id_commande, ça va aller chercher un id_commande parmi ceux qui sont possibles, si j'ai bien compris...

Dans mon cas, ça ne pose pas de problème pour le moment... et là tout de suite, j'imagine lier une nouvelle fois la table commande sous un autre nom (commande AS commande_bis) où il récupère l'id_commande de l'entrée qui a le même id_contact et la même date... ce qui devrait fonctionner. Un truc genre :

CODE
[...] LEFT JOIN commande AS commande_bis ON commande_bis.id_contact=contact.id_contact [...] WHERE [...] AND commande_bis.date=max(commande.date) [...]

Bon, je ne sais pas si c'est possible ; je testerais si j'en ai besoin...

Merci pour les autres suggestions, Kioob. Table temporaire ou vue, ce n'est pas envisageable pour le moment, mais tu entendais quoi par requête imbriquée, dans ce cas ?
Kioob
Si tu fais une autre jointure alors que tes principales sont liées à coup de "group by", ça peut vite devenir imbuvable comme requête (coté perfs, j'ai du mal à me faire une idée par contre).

Du coup j'aurais tendance à séparer de cette manière :
CODE
select XXXX
from table3, (
    select ZZZZ, YYYY
    from table1
    left join table2 on [...]
    where [...]
    group by ZZZZ
    ) t4
where t3.bidule = t4.chose


Ce n'est pas forcément mieux... il faudrait un exemple concret, mais dans l'idée c'est ça.

Enfin coté lisibilité, la vue est encore mieux et fait à priori exactement la même chose.
aspeum
Avec beaucoup de retard, je tiens à te remercier, parce que ta suggestion de requête imbriquée était la bonne. J'ai testé une vue, mais je devais en créer plusieurs, et ça finissait pas être compliqué...
Kioob
Mais de rien smile.gif
Ceci est une version "bas débit" de notre forum. Pour voir la version complète avec plus d'information, la mise en page et les images, veuillez cliquer ici.