Bonjour a tous, j'aimerais injecter des donnes dans une liste deroulante, mais au moment de le faire , les donnes qui a dans la liste sont en double, a cause de l'ID qui est diferente pour les memes donnes, je mexplique:
et la le resultat:
J'ai different mois d'observation pour les memes années, mais j'ai besoin de ce filtre pour aprés choisir les mois.
Soit tu affiches deux balises <select>, une avec les années, et une avec les mois ... Celle des mois peut d'ailleurs être saisie "à la main" (valeur de 1 à 12) ...
Merci Benzouye pour la reponse et pour déplacer le post de forum, et je m'excuse de l'erreur :s:s:s
En gros toutes les donnes sont dans la meme table, les mois je peux pas l'es introduir a la main parce que l'utilisateur est capable de choisir un mois ou il y a pas de donnees x)
j'ai une table avec mois_observation , annee et mois,
le format est le suivant: mois_observation 201701 / anne 2017 / mois 01 ;
je peux pas modifier la BDD donc je peux pas faire autrement que comem ça , du coup pour 201701 , 201702 etc, l'annee va etre la meme, mais pas le mois_d'observation, du coup au moment de faire un SELECT DISTINC il me renvois tous les mous_observation different, mais les memes années :s j'espere m'avoir bien expliqué x)
Peut-on avoir un exemple de données, une ou deux lignes de ta table ?
SalvadorAguilarRubio a écrit:
l'utilisateur est capable de choisir un mois ou il y a pas de donnees
Alors tu dois fonctionner en deux étapes, deux requêtes, deux <select>. D'abord afficher la liste des années distinctes dans une balise <select>.
Ensuite deux possibilités pour aller chercher en base les mois distincts correspondants à l'année renseignée. Soit tu fonctionnes avec un rechargement de la page, soit tu fonctionnes avec JavaScript/AJAX sans rechargement.
non la dans le select 2017, il y a que 8 mois, vu que ce mois-ci il a pas encore été injecté dans la BDD, et le SELECT DISTINCT ne marche pas a cause de les ID, qui sont différent a chaque mois, avec cette requête , j'aurais autant de résultats dans le select que de mois, parce que j'ai une ID different pour chaque année.. est ce qu'il y a un moyenne pour faire un select normal et un select distinct dans la meme requete ?? :s
- Edité par SalvadorAguilarRubio 18 septembre 2017 à 15:03:48
Pas sûr d'avoir tout saisi non plus, mais si tu as plusieurs enregistrements avec le même mois_observation il faut utiliser un GROUP BY pour regrouper uniquement sur ce qui t'interesse:
SELECT mois_observation, annee, mois
FROM tatable
GROUP BY annee, mois
ORDER BY annee DESC, mois DESC
Si tu découpes le mois et l'année dans deux select different, tu n'as aucun moyen (autre qu'avec du PHP) de verifier que le combo annee + mois soit une date qui existe dans ta base de données, c'est pour cela qu'on te dit de directement afficher l'année + le mois dans le même select pour qu'on puisse uniquement selectionner des dates valides par defaut, c'est plus utile pour l'utilisateur final, il voit ce qu'il y a ou non.
- Edité par Sombrelune 18 septembre 2017 à 15:22:21
- Activer les erreurs : PHP - PDO-MYSQLI - ¯\_ツ_/¯ - Documentations :PHP - MySQL -
si je l'au l, mais désolé j'ai un peu du mal avec le français par foi, c'est pas ma langue maternelle :s la requete que t'as ecrit est tres interessant je savais pas qu'on pouvais faire ça, mais malheureusement c'est pas est que je cherche
je voudrais une liste pour les années et une autre pour les mois, la y'a un petit bout de ma table:
- Edité par SalvadorAguilarRubio 18 septembre 2017 à 15:24:56
Si tu ne veux que les années uniques, mets seulement l'année dans le GROUP BY, mais comme expliqué plus haut, faire deux <select> c'est se compliquer la vie.
SELECT mois_observation, annee
FROM tatable
GROUP BY annee
ORDER BY annee DESC
Note: Dans ce cas la le mois_observation est carrément pas fiable, il va prendre la valeur du premier mois + annee trouvé dans la table (il vaut mieux ne pas l'utiliser tel quel).
- Edité par Sombrelune 18 septembre 2017 à 15:33:39
- Activer les erreurs : PHP - PDO-MYSQLI - ¯\_ツ_/¯ - Documentations :PHP - MySQL -
Oui vous avez raison, j'essaye de faire les deux donnés dans la mémé liste déroulante, du coup la requete que je vais mettre c'est :
SELECT mois_observation, annee, mois FROM dr GROUP BY annee, mois ORDER BY annee DESC, mois DESC
est ce que le code PHP pour placer les données dans la liste serais celui-ci ?
<?php
$reponseCrit = $bdd->query('SELECT mois_observation, annee, mois
FROM dr
GROUP BY annee, mois
ORDER BY annee DESC, mois DESC');
while($row = $reponseCrit->fetch()){
echo "<option value='".$row["ID_agence"]."'>"..$row['annee'].'-'.$row['mois']."</option>";
}
?>
c'est bon ce code marche pas du tou , j'ai fait pas mal d'erreurs de syntaxe x) le bon code c'est celuila :
<?php
$reponseCrit = $bdd->query('SELECT mois_observation, annee, mois
FROM dr
GROUP BY annee, mois
ORDER BY annee DESC, mois DESC');
while($row = $reponseCrit->fetch()){
echo "<option value='".$row["mois_observation"]."'>".$row['annee'].'-'.$row['mois']."</option>";
}
?>
Merci pour tout , une derniere question, avant de marquer le post comme resolu, pour faire un trie de date de plusierurs mois, toujours en periode , ex: "janvier, fevrier, mars" ou "aout, septembre, octobre" , vous ferais comment ? Merci encore!!!
- Edité par SalvadorAguilarRubio 18 septembre 2017 à 15:46:02
Oui merci j'ai fais comme ça la modif c'etait pour avoir des indices pour faire un trie pour periodes, pour selectioner le mois de debut et de fin de la periode (ex: janvier jusqua mars)
si tu as plusieurs enregistrements avec le même mois_observation il faut utiliser un GROUP BY pour regrouper uniquement sur ce qui t'interesse
Non, c'est le rôle de DISTINCT de supprimer les doublons ! GROUP BY sera utile en cas de d'utilisation de fonction d'agrégat (SUM, COUNT, AVG, MIN, MAX, etc.). Un peu de lecture pour clarifier cette erreur fréquemment induite par MySQL.
Sombrelune a écrit:
Si tu ne veux que les années uniques, mets seulement l'année dans le GROUP BY
Non, pour les mêmes raisons que précédemment ... De plus, un mois aléatoire serait remonté pour chaque année ...
Y'a aussi la solution de mettre à jour la langue sur MySQL et ensuite de formater une date valide (à partir de ton année et de ton mois) avec DATE_FORMAT() ou récupérer le mois directement avec MONTHNAME() mais bon je vais pas rentrer dans les details, ça fait faire une requete SQL en plus si tu n'as pas la main sur le serveur MySQL.
@Benzouye:
Oui, j'en suis très conscient, mais GROUP BY ne fait pas la même chose que DISTINCT. DISTINCT supprime les doublons sur toute la selection (e.g. en prenant en compte la totalité des champs séléctionnés) alors que GROUP BY peut très bien cibler un seul champ (qui n'est pas forcément dans la clause SELECT). Les deux mots clés ont leur propres spécificités et il n'est pas du tout invalide d'utiliser GROUP BY pour de la suppression de doublon, évidement il est préférable d'utiliser DISTINCT pour de simples tables et pour simplement supprimer les doublons sur la totalité de la séléction, mais les pertes de performances restent plus que négligables pour une utilisation aussi simple que celle de SalvadorAguilarRubio. J'ai vonlontairement utilisé GROUP BY par défaut car je n'étais pas sûr de ce qu'il voulait récupérer dans sa requete finale (et ce que contenait mois_observation, qui n'est finalement pas un id unique), maintenant qu'on sait ce qu'il veut faire / ce qu'il a, effectivement, il peut utiliser un DISTINCT.
SELECT DISTINCT mois_observation, annee, mois
FROM dr
ORDER BY annee DESC, mois DESC
Note que le mois séléctionné dans la requete SQL avec le GROUP BY uniquement sur l'annee ne séléctionera pas un mois_observation aléatoire, mais le premier recontré par le SGBD pour le groupe de résultat donné (après l'ordre dépend des index et de l'ordre d'insertion dans la table). Bref, c'est l'equivalent du ANY_VALUE dans les dernieres versions de MySQL, où une telle requete n'est pas autorisée car le resultat n'est pas fiable (il faut explicitement spécifier quelle valeur on veut dans le groupe de données).
- Edité par Sombrelune 18 septembre 2017 à 16:56:01
- Activer les erreurs : PHP - PDO-MYSQLI - ¯\_ツ_/¯ - Documentations :PHP - MySQL -
DISTINCT supprime les doublons sur toute la selection (e.g. en prenant en compte la totalité des champs séléctionnés) alors que GROUP BY peut très bien cibler un seul champ (qui n'est pas forcément dans la clause SELECT).
Non, c'est une mauvaise utilisation du GROUP BY de ta part, induite par la façon dont il a été implémenté dans MySQL. Je te conseille la lecture de cet article pour approfondir la question
D'ailleurs depuis sa version 5.7.5, MySQL n'accepte plus par défaut que le SELECT soit différent du GROUP BY (option only_full_group_by) comme la plupart des SGBDR du marché. Cela induit au final un résultat "aléatoire" sur les colonnes hors du GROUP BY ... Faire un GROUP BY avec des colonnes présentes au SELECT mais absentes du GROUP BY n'a selon moi pas de sens ... Je n'ai rencontré aucun cas particulier où le comportement de MySQL < 5.7.5 avait un intérêt, vu que le contenu des colonnes hors GROUP BY ne répond pas à une logique déterminée ... Si tu veux regrouper sur une colonne et que tu te fout des valeurs des autres (mmmm ANY_VALUE() ), alors autant ne pas les mettre ou autant maîtriser ces valeurs avec des fonctions d'agrégat ...
Je n'ai lu que dans les grandes lignes, par avance désolé. Benzouye, j'irais jeter un œil à tes liens, culture G
Je m'étonne que personne ne lui ait conseillé de revoir son architecture de table pour nous mettre un joli champ DATE à la place de ses 3 champs qui au final n'en font qu'un.
Avec les fonctions YEAR() et MONTH() de MySQL, il serait deja plus facile de jouer sur les dates lors de recherches. Et si je ne m'abuse, ça aiderait aussi dans la résolution de son problème non ?
A moins que je me trompe, et corrigez moi si c'est le cas ...
Je m'étonne que personne ne lui ait conseillé de revoir son architecture de table pour nous mettre un joli champ DATE à la place de ses 3 champs qui au final n'en font qu'un.
C'est pas faux D'autant que ses trois colonnes occupent au moins (selon le type utilisé) 9 octets contre 3 seulement pour une seule colonne DATE ...
Ealon a écrit:
ça aiderait aussi dans la résolution de son problème non ?
Au final il aura toujours besoin de retrouver les années et mois distincts ... et les fonctions YEAR et MONTH rajoutent un poil de temps de traitement ... mais là on chipote
Je m'étonne que personne ne lui ait conseillé de revoir son architecture de table pour nous mettre un joli champ DATE à la place de ses 3 champs qui au final n'en font qu'un.
J'y ai pensé également, mais l'auteur a spécifié qu'il ne pouvait pas changer la structure de la base de données (cf. ce message). Mais tous le monde est d'accord, il est 1000 fois plus simple de manipuler des dates quand elles sont stoquées avec des types appropriés (DATE, DATETIME).
Benzouye a écrit:
Faire un GROUP BY avec des colonnes présentes au SELECT mais absentes du GROUP BY n'a selon moi pas de sens ... Je n'ai rencontré aucun cas particulier où le comportement de MySQL < 5.7.5 avait un intérêt, vu que le contenu des colonnes hors GROUP BY ne répond pas à une logique déterminée ... Si tu veux regrouper sur une colonne et que tu te fout des valeurs des autres (mmmm ANY_VALUE() ), alors autant ne pas les mettre ou autant maîtriser ces valeurs avec des fonctions d'agrégat ...
Je repensais à ca aujourd'hui et j'ai trouvé un contre-exemple :
SELECT m.*, u.*
FROM (
SELECT *
FROM `messages`
ORDER BY `date` DESC
) AS m
INNER JOIN `tbl_users` AS u
ON m.`id_expediteur` = u.`userID`
GROUP BY m.`id_expediteur`
WHERE m.`id_destinataire` = ...
ORDER BY m.`date` DESC
Cette requete SQL, qui vient d'un autre topic du forum, est basé sur un systeme de messagerie et elle permet de récupérer uniquement le dernier message de toutes les conversations entre l'utilisateur courant et ses amis.
Dans cette requete on a un GROUP BY m.`id_expediteur` (l'expediteur du message) et on utilise une sous-requete SQL à la place du FROM pour organiser l'ordre des elements AVANT le GROUP BY (ce qui n'est pas possible autrement). Du coup on peut maitriser ce que le GROUP BY va retourner, et les autres champs dans le SELECT (autre que ceux dans le GROUP BY) ont réelement un sens, ils ne sont pas "aléatoire".
- Edité par Sombrelune 21 septembre 2017 à 18:36:06
- Activer les erreurs : PHP - PDO-MYSQLI - ¯\_ツ_/¯ - Documentations :PHP - MySQL -
Je repensais à ca aujourd'hui et j'ai trouvé un contre-exemple :
SELECT m.*, u.*
FROM (
SELECT *
FROM `messages`
ORDER BY `date` DESC
) AS m
INNER JOIN `tbl_users` AS u
ON m.`id_expediteur` = u.`userID`
GROUP BY m.`id_expediteur`
WHERE m.`id_destinataire` = ...
ORDER BY m.`date` DESC
Ah ouai ... Tant de fautes dans une même requête En plus du GROUP BY, le SELECT *, le WHERE après le GROUP BY ... qu'elle ne devrait pas être donnée en exemple et retourne une erreur de syntaxe ...
Sombrelune a écrit:
elle permet de récupérer uniquement le dernier message de toutes les conversations entre l'utilisateur courant et ses amis
Non car elle ne traite le problème que dans un sens ... il faudrait gérer expéditeur OU destinataire ...
Sombrelune a écrit:
on peut maitriser ce que le GROUP BY va retourner, et les autres champs dans le SELECT (autre que ceux dans le GROUP BY) ont réelement un sens, ils ne sont pas "aléatoire"
Je ne ferais pas confiance à cette requête car il est impossible de déterminer quelle valeur va choisir MySQL, même si l'illusion est donnée par le ORDER BY de la sous-requête et malgré le fait qu'il y ait une relation fonctionnelle entre m et u.
Doc MySQL GROUP BY à ce propos :
In this case, the server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate, which is probably not what you want
Je rappelle aussi ce lien pour ceux qui ne l'auraient pas vu/lu plus haut.
Une meilleure façon, plus sereine de faire cette requête serait :
SELECT
M.`date`,
M.id_expediteur as id_expe,
D.userID as id_dest
FROM
(
-- Date maxi par expéditeur
SELECT id_expediteur, MAX(`date`) AS max_date
FROM messages
GROUP BY id_expediteur
) MD
INNER JOIN messages M
ON MD.id_expediteur = M.id_expediteur
AND MD.max_date = M.`date`
INNER JOIN tbl_users AS D
ON M.id_destinataire = D.userID
WHERE M.`id_destinataire` = ...
ORDER BY M.`date` DESC
Bon, désolé de polluer ce sujet avec ces échanges, mais je trouve important de vraiment clarifier ce point souvent mécompris ...
La lecture des liens donnés pourront aider les plus curieux
[requete multiple] Valeurs en double avec DISTINCT
× 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.
Keep It Simple Stupid - SF4 conf Swift - Cours 1/4 SF4 - Exceptions PDO - Formes Normales