Aller au contenu

Épurer les résultats suite à un LEFT JOIN


aspeum

Sujets conseillés

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 :

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 :

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 :

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.

Lien vers le commentaire
Partager sur d’autres sites

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.

Lien vers le commentaire
Partager sur d’autres sites

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 ?

Modifié par aspeum
Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

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 :

[...] 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 ?

Modifié par aspeum
Lien vers le commentaire
Partager sur d’autres sites

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 :

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.

Lien vers le commentaire
Partager sur d’autres sites

  • 2 semaines plus tard...

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é...

Lien vers le commentaire
Partager sur d’autres sites

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...