Ne pas afficher les boublons?

Eléphanteau du PHP | 44 Messages

14 sept. 2006, 12:42

Bonjour,

Voici ma requête. Pour le moment tout s'affiche. Mais je souhaiterais ne pas afficher les doublons.
SELECT id_newsletter, titre
FROM newsletter
ORDER BY `position` ASC
La valeur 'titre' est parfois la même valeur.

Merci.
Pierre

Eléphanteau du PHP | 44 Messages

14 sept. 2006, 13:05

J'ai partiellement résolu le problème:
SELECT DISTINCT newsletter.titre
FROM newsletter
ORDER BY `position` ASC
Mais si je souhaite ajouter 'newsletter.id_newsletter' à la sélection ça ne fonctionne plus.

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

14 sept. 2006, 13:20

En principe le modificateur DISTINCT permet à une requête SELECT de ne retourner que les résultats sans-doublons. C'est à dire d'éliminer les lignes strictement identiques où tous les champs ont la même valeur et non pas des lignes où seulement quelques champs mais pas tous sont identiques.

Autrement dit, si le résultat d'une requête "SELECT DISTINCT champ1, champ2, champ3 FROM laTable;" est le suivant:
  • 1, "Cours PHP", "de l'auteur: toto"
    2, "Cours MySQL", "de l'auteur: toto"
    3, "Cours PHP", "d'un autre auteur"
Toutes les lignes sont distinctes même s'il y a des lignes où les valeurs de certains champs sont les mêmes.

Pour éliminer alors le doublon "Cours PHP", la requête ne doit retourner que ce champ en commutant vers le mode DISTINCT.
Cette requête s'écrit alors : SELECT DISTINCT champ2 FROM laTable;

Si toutefois on a besoin de tous les champs, l'élimination des doublons peut être faite par programmation et pour cela il faut d'abord organiser (trier ou regrouper) le résultat de la requête par le champ qui autorise les doublons pour profiter de ce classement dans l'exploitation (lecture) du résultat et ainsi ne traiter les valeurs qui se répètent qu'une seule fois à tout changement.

Une technique plus pratique consiste à stocker ce résultat dans un tableau associatif à 2 dimensions où la première dimension est indexée par le champ des doublons comme ça une occurrence de cet index correspondra dans la seconde dimensions aux occurrences des autres champs (une relation 1/N en quelque sorte).

Exemple :
$Requête = "SELECT DISTINCT champ2, champ3, champ1 FROM laTable ORDER BY champ2"; 
Le résultat est le suivant:
  • "Cours MySQL", "de l'auteur: toto", 2
    "Cours PHP", "de l'auteur: toto", 1
    "Cours PHP", "d'un autre auteur", 3
Le stockage de ce résultat dans un tableau associatif à 2 dimensions hiérachisées devera donner:
  • $tableau["Cours MySQL"][0] = array ("de l'auteur: toto", 2);
    $tableau["Cours PHP"][0] = array ("de l'auteur: toto", 1);
    $tableau["Cours PHP"][1] = array ("d'un autre auteur", 3);
Seulement ce tableau doit être construit dynamiquement par php à partir du résultat de la requête SQL. Le code est le suivant:
//Après l'exécution de la requête, la lire:
while ($ligne = mysql_fetch_assoc($resultat)){
   $tableau["$ligne[champ2]"][]= array($ligne[champ3], $ligne[champ1]);
}

echo "<pre>"; print_r($tableau); echo "</pre>"; //afficher pour débuguer
Ainsi pour afficher ce résultat par groupe de champ2 sous cette forme:
Cours MySQL
  • de l'auteur: toto
    2
Cours PHP
  • de l'auteur: toto
    1
    d'un autre auteur
    3
Le code php est le suivant :
//Afficher pour 1 valeur de champ2 : N valeurs de champ3 et champ1
if ($tableau) foreach ($tableau as $champ2=>$contenu){//1° dimension
   echo "<h3>$champ2</h3><ul>"; //titre de liste
   if ($contenu) foreach ($contenu as $valeur){ //2° dimension
      echo "<p>$valeur</p>";
   }
   echo "</ul>"; //fin liste
}
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène