rechercher le dernier doublon [MYSQL] - SQL/NoSQL - Programmation
Marsh Posté le 19-03-2012 à 17:27:42
SELECT * FROM table t, (SELECT MAX(ID) as MaxID FROM table GROUP BY nom) AS Tmp WHERE t.ID = Tmp.MaxID AND t.Present = 'Y' ORDER BY DateMvt
Marsh Posté le 20-03-2012 à 09:15:07
Wahou !
J'avoue ne pas très bien comprendre la subtilité de la requête mais elle fonctionne parfaitement.
Un très GRAND MERCI à toi
Marsh Posté le 20-03-2012 à 09:44:14
La sous-requête permet, pour chaque nom, de récupérer l'ID du mvt le plus récent. La requête principale permet de récupérer le détail des ID max ainsi récupéré, triés par date de mvt.
En effet, le group by regroupe les lignes (ici, sur le critère "nom" ) mais ne garde pas la correspondance entre les valeurs des champs. Les valeurs retournées vont dépendre de la clause order by. Le group by peut donc remonter pour un "nom", un certain ID mais une date de mvt qui ne correspond pas à l'ID.
Marsh Posté le 20-03-2012 à 10:49:26
Merci pour ces explications. J'apprécie la démarche d'expliquer la solution.
Mais comme rien n'est simple dans ce bas monde informatique ....
La requète présentée dans ma demande n'est en fait qu'une partie de la recherche. Je l'avais simplifié pour en faire ressortir le besoin.
Ma table est une table de mouvements d'objets. Elle contient d'autres champs. Je dois arriver à afficher la dernière position de chaque objet à une date donnée.
J'ai donc rajouter une close à WHERE
SELECT * FROM mvt, (SELECT MAX(ID) as MaxID FROM mvt GROUP BY nom) AS Tmp WHERE mvt.ID = Tmp.MaxID AND mvt.Present = 'Y' AND mvt.DateMvt <= '$DJE' AND mvt.DateMvt IS NULL ORDER BY Nom ASC
($DJE étant la date à laquelle les mouvements ont eu lieu)
La requète donne de bons résultats si la date de recherche ($DJE) est supérieure ou égale à la date du dernier mouvement d'un objet.
Ex
ID 1 : date du mouvement: 2012-03-01
ID 1 : date du mouvement: 2012-03-02
ID 1 : date du mouvement: 2012-03-03
$DJE = 2012-03-03
la requête retourne
résultat= Objet 1 dernier mouvement le 2012-03-03
si $DJE = 2012-03-02
la requête ne retourne rien
Je pense que c'est une question d'ordre de recherche dans la requête mais je ne vois pas comment m'y prendre.
Marsh Posté le 20-03-2012 à 11:51:00
Le where n'est pas bon : mvt.DateMvt <= '$DJE' AND mvt.DateMvt IS NULL
Comment veux-tu que la date soit à la fois <= à une donnée et être NULL. Je pense que le where devrait être :
((mvt.DateMvt <= '$DJE') OR (mvt.DateMvt IS NULL))
Les parenthèses sont très importantes!
Marsh Posté le 20-03-2012 à 11:58:15
Oups !
effectivement c'est une belle erreur de recopie
Voila ra requete qui sort du copier/coller
SELECT * FROM mvt, (SELECT MAX(ID) as MaxID FROM mvt GROUP BY nom) AS Tmp WHERE mvt.ID = Tmp.MaxID AND mvt.Present = 'Y' AND mvt.DateJour <= '$DJE' AND mvt.DateSortie IS NULL ORDER BY Nom ASC
Marsh Posté le 20-03-2012 à 13:35:56
SELECT * FROM table t, (SELECT MAX(ID) as MaxID FROM table GROUP BY nom) AS Tmp WHERE t.ID = Tmp.MaxID AND t.Present = 'Y' AND ((mvt.DateMvt <= '$DJE') OR (mvt.DateMvt IS NULL)) ORDER BY DateMvt
Marsh Posté le 20-03-2012 à 14:17:53
Cela ne fonctionne toujours pas
la requète donne une erreur: Unknown column 'mvt.DateJour' in 'where clause'
je l'ai modifié comme suit:
SELECT * FROM mvt t, (SELECT MAX(ID) as MaxID FROM mvt GROUP BY nom) AS Tmp WHERE t.ID = Tmp.MaxID AND t.Present = 'Y' AND ((DateJour <= '$DJE') OR (DateJour IS NULL)) ORDER BY DateJour
Voici ma table mvt
ID Nom Mouvement Ch DateJour Service ServiceOld Present DateSortie
1 test1 E 100 2012-03-12 00:00:00 MCO1 NULL Y NULL
2 test2 E 400 2012-03-13 00:00:00 MCO4 NULL Y NULL
3 test3 E 300 2012-03-13 00:00:00 SSR NULL Y NULL
4 test4 E 350 2012-03-19 00:00:00 USLD NULL Y NULL
5 test5 E 1023 2012-03-17 00:00:00 MCOP NULL Y NULL
6 test1 M 401 2012-03-18 00:00:00 SSR MCO1 Y NULL
7 test6 E 20 2012-03-10 00:00:00 MCO1 NULL Y 2012-03-18 00:00:00
9 test6 S NULL 2012-03-18 00:00:00 NULL MCO1 N 2012-03-18 00:00:00
10 test7 E 403 2012-03-19 00:00:00 SSR NULL Y NULL
11 test7 M 41 2012-03-19 00:00:00 MCO4 SSR Y NULL
Voici le résultat de la requete quand $DJE = 2012-03-18 00:00:00:
ID Nom Service ch date mouvement Provenance
3 test3 SSR 300 13/03/2012 E
2 test2 MCO4 400 13/03/2012 E
5 test5 MCOP 1023 17/03/2012 E
6 test1 SSR 401 18/03/2012 M MCO1
on voit bien que le dernier mouvement du nom test1 est le 18/03/2012
Voici maintenant le résultat de la requete quand $DJE = 2012-03-17 00:00:00:
ID Nom Service ch date mouvement Provenance
3 test3 SSR 300 13/03/2012 E
2 test2 MCO4 400 13/03/2012 E
5 test5 MCOP 1023 17/03/2012 E
On constate que le nom test1 n'apparait pas alors que dans la ligne 1 de la table, sa DateJour est 2012-03-12 00:00:00 (inférieure à 2012-03-17 00:00:00.
Je pense qu'il fait un group by sur le plus grand ID de Nom puis qu'il passe ce résultat dans la close WHERE. Ne peut on pas faire l'inverse, CAD passer par le where puis faire le group by ?
Marsh Posté le 20-03-2012 à 14:57:47
J'ai supposé que qu'un ID supérieur à un autre avait aussi sa date de mvt > à l'autre.
Je t'ai fait la requête, t'as plus qu'à adapter en fonction du critère de regroupement.
Marsh Posté le 19-03-2012 à 16:58:07
Bonjour,
j'ai une table mysql composée des champs suivants:
ID , nom , mvt, DateMvt, present
je cherche à récupérer toutes les lignes dont le champ present = Y sans doublon sur le nom et avec la dernière date de DateMvt.
ID| nom | mvt |DateMvt | Present
1 | Nom1 | S | 2012-03-01 | Y
2 | Nom2 | E | 2012-03-02 | Y
3 | Nom1 | M | 2012-03-04 | Y
le résultat doit etre:
2 | Nom2 | E | 2012-03-02 | Y
3 | Nom1 | M | 2012-03-04 | Y
J'ai essayé avec GROUP BY nom, mais cela ne me retourne que le 1er enregistrement (dans ce cas 1 | Nom1 | S | 2012-03-01 | Y)
merci de votre aide