J’ai le problème suivant, j'ai deux champs d'entiers (ID1 et ID2) et je souhaiterais récupérer la valeur max de ID2 pour chaque ID1.
Contrainte : ID1 contient des entiers qui se répètent.
Je souhaiterais donc récupérer le plus grand ID2 de chaque ID1 (par exemple ici ID2=52 pour ID1=1, ID2=35 pour ID1=2, ID2=309 pour ID1 =5 et ID2=55 pour ID1=8).
Est-il possible de faire cela sans passer par 2 requêtes ? Si oui comment structurer la sous-requête ?
J’ai pensé à passer par deux SELECT DISTINCT ID1 FROM ma_table et SELECT MAX(ID2) FROM ma_table puis combiner les valeur reçu d'une requête pour m'en servir dans l'autre.
Mais je trouve que ça ne fait pas très propre
Mais en faite chez moi ca prend le plus petit id2 pour chaque id1
Je crois que ca prend le premier id1 (dont le id2 est le plus petit) et laisse les autres id1 de coté
Bonjour, pour commencer j'ai résolu mon problème et je vais vous expliquer comment je m'y suis pris.
La méthode d'Angelo ne marche malheureusement pas pour mon cas car n'étant pas rentré dans les détails de mon problème, dans la requête :
select max(id2) from latable group by id1
Je dois en faite retourner plusieurs valeurs comme ceci :
select max(id2), champX, champX from latable where bidule='parametre' group by id1
Sauf que... ça ne marche pas
Donc je fais :
TANT QUE select distinct id1 from latable where bidule='parametre' /*tout les id1 où il y a bidule égal au paramètre*/
TANT QUE select max(id2) from latable where id1='id1' /*on selectionne tout les id2 les plus élevés où les lignes id1 ont bidule = 'parametre' */
select champX, champY from latable where id1='id1' and id2='id2' /*et le tour est joué !!!*/
FIN TANT QUE
FIN TANT QUE
Alors histoire que cet algorithme serve à quelqu'un, il s'agit de donner un nom unique à une chaine de caractères :
ex : SalutCaVa1.0 SalutCaVa1.1 SalutCaVa1.x etc
avec SalutCaVa id1 . id2
Voila, un grand merci à Angelo tout de même pour m'avoir aidé à mieux comprendre le group by (que je n'utilisais pas avant...)
PS: si vous connaissez un algo plus court ce serait gentil !
On écrit pas un algorithme quand on a besoin d'une requête, on écrit une requête. Là, j'ai l'impression que tu es en train de faire une requête dans une boucle imbriquée... deux fois plutôt qu'une. C'est la pire solution et la chose à ne jamais faire.
Lorsque tu as un problème, décris-le toujours précisément avec les vraies variables. C'est complètement inutile de nous donner un exemple semblable, dans la majorité des cas il y a toujours une contrainte qui a été oubliée. C'est une perte de temps autant pour toi que pour les gens qui essaient de t'aider.
Bref, tu sembles vouloir une requête dans ce genre :
SELECT colX, colY
FROM ta_table
INNER JOIN (SELECT id1, MAX(id2) AS id2
FROM ta_table
GROUP BY id1) tmp
USING (id1, id2)
Mais comme on a ni structure des tables, ni jeu d'essai, ni énoncé précis, c'est difficile de faire quelque chose de correct.
Je cherchais justement une sous-requête dans ce genre, parce qu'actuellement je suis obligé de passer par 3 requêtes pour arriver à ce que je souhaite.
Mais il y a une chose que je n'ai pas compris, n'ayant jamais utilisé de USING, je ne comprend pas ce que signifie le : tmp juste avant.
Que signifie tmp ? Est ce une nouvelle table ? Parce que pour mon cas, tout se joue sur les colonnes d'une seule et même table.
C'est une jointure. En gros, si tu connais INNER JOIN ... ON ..., c'est pratiquement identique. La seule différence, c'est que USING regroupe les colonnes identiques.
Pour tmp, c'est un alias. Lorsqu'on utilise une sous-requête comme table, il faut nécessairement lui donner un alias, mais si on ne s'en sert pas. Dans ce cas-ci, c'est inutile, mais si j'avais utilisé la syntaxe avec ON, j'aurais dû écrire quelque chose comme -- ...ONta_table.id1=tmp.id1ANDta_table.id2=tmp.id2
Bonjour Fayden, cette sous-requête fonctionne très avec USING ou ON.
Ainsi dans la table ta_table je peux récupérer tout les plus grands id2 de chaque id1 et y relever les paramètres colX et colY avec :
Avec USING :
SELECT colX, colY FROM ta_table INNER JOIN (SELECT id1, MAX(id2) AS id2 FROM ta_table GROUP BY id1) tmp USING (id1, id2)
Ou bien avec ON :
SELECT colX, colY FROM ta_table INNER JOIN (SELECT id1, MAX(id2) AS id2 FROM ta_table GROUP BY id1) tmp ON ta_table.id1 = tmp.id1 AND ta_table.id2 = tmp.id2
La touche finale que je souhaiterais y apporter, c'est d'ajouter une condition avec WHERE pour utiliser un filtre supplémentaire (de deux champs cond1 et cond2 appartenant aussi à ta_table), malheureusement, cela ne fonctionne pas :
SELECT colX, colY FROM ta_table INNER JOIN (SELECT id1, MAX(id2) AS id2 FROM ta_table WHERE (ta_table.cond1='$cond1') AND (ta_table.cond2='$cond2') GROUP BY id1) tmp ON ta_table.id1 = tmp.id1 AND ta_table.id2 = tmp.id2
SELECT colX, colY FROM ta_table INNER JOIN (SELECT id1, MAX(id2) AS id2 FROM ta_table GROUP BY id1) tmp ON ta_table.id1 = tmp.id1 AND ta_table.id2 = tmp.id2 WHERE (ta_table.cond1='$cond1') AND (ta_table.cond2='$cond2')
SELECT colX, colY FROM ta_table INNER JOIN (SELECT id1, MAX(id2) AS id2 FROM ta_table WHERE (ta_table.cond1='$cond1') AND (ta_table.cond2='$cond2') GROUP BY id1) tmp ON ta_table.id1 = tmp.id1 AND ta_table.id2 = tmp.id2 WHERE (ta_table.cond1='$cond1') AND (ta_table.cond2='$cond2')
PS: J'ai choisis l'exemple avec ON parce que je suis habitué aux INNER JOIN...
Où peut-on placer le WHERE dans la structure de ce type de requête ?
Je vous remercie.
Selectionner valeu max d'une colonne par rapport à une autre
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
et GG