IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

[SQL] Eviter doublons dans un select (sans DISTINCT)


Sujet :

PHP & Base de données

  1. #1
    Membre averti Avatar de renaud26
    Homme Profil pro
    Webmaster
    Inscrit en
    Mars 2003
    Messages
    1 365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 365
    Points : 436
    Points
    436
    Par défaut [SQL] Eviter doublons dans un select (sans DISTINCT)
    Bonjour à tous,

    Je voudrais récupérer le champ "mots-clefs" d'une table qui comporte une dizaine de lignes.
    la 1ere comporte: toto, tata, velo, moto
    la 2eme: roue, rayon, velo, moteur, guidon

    Ma question: comment ne pas récupérer (ou ne pas afficher) 2 fois "vélo" dans le résultat sachant que DISTINCT et GROUP BY ne fonctionnent pas dans ce cas ?

  2. #2
    Membre expert

    Profil pro
    imposteur
    Inscrit en
    Avril 2003
    Messages
    3 308
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : imposteur

    Informations forums :
    Inscription : Avril 2003
    Messages : 3 308
    Points : 3 377
    Points
    3 377
    Par défaut
    Montre-nous comment tu utilises DISTINCT

  3. #3
    Membre averti Avatar de renaud26
    Homme Profil pro
    Webmaster
    Inscrit en
    Mars 2003
    Messages
    1 365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 365
    Points : 436
    Points
    436
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     
    $sql = mysql_query("SELECT DISTINCT mots_clefs FROM keywords GROUP BY mots_clefs");
    je précise que j'ai le même résultat avec ou sans la clause GROUP BY

  4. #4
    Membre expert

    Profil pro
    imposteur
    Inscrit en
    Avril 2003
    Messages
    3 308
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : imposteur

    Informations forums :
    Inscription : Avril 2003
    Messages : 3 308
    Points : 3 377
    Points
    3 377
    Par défaut
    Pardon j'avais pas vraiment compris ce que tu voulais faire.
    Je ne pense pas que tu puisses faire ça en SQL, il va falloir faire une élimination des doublons en PHP. J'ai pas d'algo optimisé en tête.

  5. #5
    Membre averti Avatar de renaud26
    Homme Profil pro
    Webmaster
    Inscrit en
    Mars 2003
    Messages
    1 365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 365
    Points : 436
    Points
    436
    Par défaut
    ça fait un moment que je me creuse la tête sans succès avec ce truc qui parait simple...t'aurais pas une piste, tuto vers où je pourrais chercher ?

  6. #6
    Membre expert

    Profil pro
    imposteur
    Inscrit en
    Avril 2003
    Messages
    3 308
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : imposteur

    Informations forums :
    Inscription : Avril 2003
    Messages : 3 308
    Points : 3 377
    Points
    3 377
    Par défaut
    Citation Envoyé par renaud26
    ça fait un moment que je me creuse la tête sans succès avec ce truc qui parait simple...t'aurais pas une piste, tuto vers où je pourrais chercher ?
    Non, si je devais le faire sans trop de contraites j'irais "brutal", je parcourrais tout pour trouver les doublons... Pas super question algo... Peut-être que si tu postes sur algo justement, on te donnera des idées plus intelligentes.

  7. #7
    Membre émérite

    Homme Profil pro
    Expert PHP
    Inscrit en
    Novembre 2004
    Messages
    2 127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Expert PHP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 127
    Points : 2 557
    Points
    2 557
    Par défaut
    si tu stockes les deux résultats dans le meme tableau, apres tu fais :
    http://fr.php.net/manual/fr/function.array-unique.php

    voila.

  8. #8
    Membre averti Avatar de renaud26
    Homme Profil pro
    Webmaster
    Inscrit en
    Mars 2003
    Messages
    1 365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 365
    Points : 436
    Points
    436
    Par défaut
    justement, "parcourir tout pour éliminer les doublons", je vois pas trop comment faire ça en php...ranger les réponses dans un tableau et le parcourir ?

  9. #9
    Membre expert

    Profil pro
    imposteur
    Inscrit en
    Avril 2003
    Messages
    3 308
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : imposteur

    Informations forums :
    Inscription : Avril 2003
    Messages : 3 308
    Points : 3 377
    Points
    3 377
    Par défaut
    Citation Envoyé par Maxoo
    si tu stockes les deux résultats dans le meme tableau, apres tu fais :
    http://fr.php.net/manual/fr/function.array-unique.php

    voila.
    Juste avant ça, tu fais un explode de toutes tes chaines de caractères, pour séparer les mots (Maxoo : c'est pas des noms, c'est des listes de noms...)

    PS Un modèle de base de données digne de ce nom t'aurait fait mettre un mot par champ, dans une seconde table, et une table de correspondance entre les deux... Ouais c'est lourd, mais t'aurais tout fait en SQL !

  10. #10
    Membre émérite

    Homme Profil pro
    Expert PHP
    Inscrit en
    Novembre 2004
    Messages
    2 127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Expert PHP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 127
    Points : 2 557
    Points
    2 557
    Par défaut
    array_unique supprimes les doublons, tu as vu mon post ?

    EDIT : exact Eusebius un petit explode quelque part

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    97
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 97
    Points : 64
    Points
    64
    Par défaut
    peut etre aussi qq chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <? 
    $conn_db =mysql_connect('localhost','root','');
    $db = mysql_select_db("base");
     
    //Création de la table temporaire
    $strsql = "CREATE TABLE tabletemp SELECT DISTINCT * FROM keywords";
    mysql_query( $strsql, $conn_db);
     
    //Vidage de la table d'origine
    mysql_query("DELETE FROM keywords", $conn_db);
     
    //Réinjection des enregistrements
    $strsql = "INSERT INTO keywords SELECT * from tabletemp";
    mysql_query($strsql, $conn_db);
     
    ?>
    ca peut peut etre t'aider

  12. #12
    Membre averti Avatar de renaud26
    Homme Profil pro
    Webmaster
    Inscrit en
    Mars 2003
    Messages
    1 365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 365
    Points : 436
    Points
    436
    Par défaut
    Merci pour ta suggestion, mais je crains que le SELECT DISTINCT ne fonctionne pas et que je reproduise aussi les doublons dans la table temp...
    Je cherche plutôt du côté de array_unique...mais je rame...

  13. #13
    Membre averti Avatar de renaud26
    Homme Profil pro
    Webmaster
    Inscrit en
    Mars 2003
    Messages
    1 365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 365
    Points : 436
    Points
    436
    Par défaut
    re,

    Voici ce que j'ai fait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
     
    $sql = mysql_query("SELECT mots_clefs FROM keywords ORDER BY mots_clefs");
     
    $ligne = "";
    while ($row = mysql_fetch_row($sql))
    {
    $chaine = explode(",",$row[0]);
    $chaine = array_unique($chaine);
     
    for($i=0;$i<sizeof($chaine);$i++){
    $ligne .= $chaine[$i]."<br>";
    }
    }
    echo $ligne;
    Alors...ça fonctionne si je ne lis qu'une ligne de la table ou il y a des doublons dans le champ "mots_clefs"...
    Mais comme je le disais au début, ma table comporte une dizaine de ligne, donc je parcours toute la table...et là, array_unique ou non, les doublons sont toujours là...

    schéma de la table
    id mots_clefs
    1 toto, tata, velo, moto
    2 roue, rayon, velo, moteur, guidon

    ...et je veux tout récup, mais pas 2 fois "velo"....

  14. #14
    Membre émérite

    Homme Profil pro
    Expert PHP
    Inscrit en
    Novembre 2004
    Messages
    2 127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Expert PHP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 127
    Points : 2 557
    Points
    2 557
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $sql = mysql_query("SELECT mots_clefs FROM keywords ORDER BY mots_clefs");
     
    $tableau_total = Array();
    while ($row = mysql_fetch_row($sql))
    {
    $chaine = explode(",",$row[0]);
    $tableau_total = array_merge($tableau_total,$chaine);
    }
    $tableau_total = array_unique($tableau_total);
    print_r($tableau_total);
    code fait a la volé, pas testé, mais l'idée est la.

  15. #15
    Membre averti Avatar de renaud26
    Homme Profil pro
    Webmaster
    Inscrit en
    Mars 2003
    Messages
    1 365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 365
    Points : 436
    Points
    436
    Par défaut
    Merci Maxoo, ta piste était bonnne...pour des questions de présentation, j'ai fait une boucle for plutôt que print_r:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
     
    $sql = mysql_query("SELECT mots_clefs FROM keywords ORDER BY mots_clefs");
     
    $tableau_total = Array();
    while ($row = mysql_fetch_row($sql))
     
    {
    $chaine = explode(",",$row[0]);
    $tableau_total = array_merge($tableau_total,$chaine);
    }
    $tableau_total = array_unique($tableau_total);
    for($i=0;$i<sizeof($tableau_total);$i++){
    echo $tableau_total[$i]."<br>";
    }
    ça s'affiche bien, et sans doublon, mais il en manque pas mal...et après la liste de mots, j'ai une série de
    Notice: Undefined offset: 46 sur ma boucle for jusqu'à l'indice 130...Si je mets la boucle for dans la boucle while, je retrouve ma liste complète, doublons compris...
    T'as une idée la dessus ?

  16. #16
    Membre émérite

    Homme Profil pro
    Expert PHP
    Inscrit en
    Novembre 2004
    Messages
    2 127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Expert PHP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 127
    Points : 2 557
    Points
    2 557
    Par défaut
    Ah oui mince, quand on fait un array_unique, il y reste de trous dans le tableau, comme tu as dit, du coup il faut refaire un array_merge dessus !!

    C'est expliqué dans la doc, j'avoue c'est pas facile à trouver, mais faut chercher aussi

    http://fr.php.net/manual/fr/function.array-merge.php
    Si vous passez un seul tableau à cette fonction et qu'il a des indices numériques, les clés seront réindexées normalement.

  17. #17
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Points : 29 985
    Points
    29 985
    Par défaut
    Salut

    La meilleure solution consiste toujours à enregistrer des données atomiques (càd les plus petites possibles) dans une table de BDD. Dans le cas qui nous occupe, cela suppose une table comme celle-ci :
    keyword(id_foreign, name);

    Sémantiquement, je trouve que c'est une erreur d'appeler une table "keywords" si tu ne lui donnes que des listes de mots clefs (pas des mots clefs isolés). Ta table actuelle devrait à la limite s'appeler "keyword_list"...

    Ta requête actuelle telle que je la vois :
    <?php
    // Pas de clause ORDER BY puisque ce ne sont de toute manière pas des mots isolés
    $sql = 'SELECT mots_clefs
    &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;FROM keywords'
    ;

    $result = mysql_query($sql) or die(__LINE__.'<br />'.mysql_error());

    //
    // Récupération des données
    //
    $keywords = array();
    while(
    $keyword = mysql_fetch_assoc($result)){
    &#160;&#160;&#160;
    //
    &#160;&#160;&#160;// Insertion seulement si absent : aucun doublon
    &#160;&#160;&#160;//
    &#160;&#160;&#160;
    if(!in_array($keyword, $keywords)){
    &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
    $keywords&#91;] = $keyword&#91;'name'];
    &#160;&#160;&#160;}
    }
    sort($keywords); // Tri des données

    //
    // Affichage final
    //
    foreach($keywords as $keyword){
    &#160;&#160;&#160;echo
    $keyword.'<br />';
    }
    ?>
    Colorez votre code PHP sur les forums grâce à Developpez.com


    Mise en aplication concrète de ce dont je te parle :
    article (id, date, author, title, text)
    keyword (id, name)
    article_keyword (#id_article, #id_keyword)
    Pour récupérer les mots clefs d'un article en particulier (dont tu as déjà l'identifiant) :
    <?php
    //
    // Requête
    //
    $sql = 'SELECT k.`name`
    &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;FROM `keyword` AS k
    &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;INNER JOIN `article_keyword` AS ak ON ak.`id_keyword` = k.`id`
    &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;WHERE ak.`id_article` = '
    .$id_article.'
    &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ORDER BY k.`name`;

    $result = mysql_query($sql) or die(__LINE__.'
    <br />'.mysql_error());

    //
    // Récupération et affichage
    //
    while($keyword = mysql_fetch_assoc($result)){
    &#160;&#160;&#160;echo $keyword&#91;'
    name'].'<br />';
    }
    ?>
    Colorez votre code PHP sur les forums grâce à Developpez.com

  18. #18
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Points : 29 985
    Points
    29 985
    Par défaut
    Salut

    La meilleure solution consiste toujours à enregistrer des données atomiques (càd les plus petites possibles) dans une table de BDD. Dans le cas qui nous occupe, cela suppose une table comme celle-ci :
    keyword(id_foreign, name);

    Sémantiquement, je trouve que c'est une erreur d'appeler une table "keywords" si tu ne lui donnes que des listes de mots clefs (pas des mots clefs isolés). Ta table actuelle devrait à la limite s'appeler "keyword_list"...

    Ta requête actuelle telle que je la vois :
    <?php
    // Pas de clause ORDER BY puisque ce ne sont de toute manière pas des mots isolés
    $sql = 'SELECT mots_clefs
    FROM keywords'
    ;

    $result = mysql_query($sql) or die(__LINE__.'<br />'.mysql_error());

    //
    // Récupération des données
    //
    $keywords = array();
    while(
    $keyword = mysql_fetch_assoc($result)){
    &#160;&#160;&#160;
    //
    &#160;&#160;&#160;// Insertion seulement si absent : aucun doublon
    &#160;&#160;&#160;//
    &#160;&#160;&#160;
    if(!in_array($keyword&#91;'name'], $keywords)){
    &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
    $keywords&#91;] = $keyword&#91;'name'];
    &#160;&#160;&#160;}
    }
    sort($keywords); // Tri des données

    //
    // Affichage final
    //
    foreach($keywords as $keyword){
    &#160;&#160;&#160;echo
    $keyword.'<br />';
    }
    ?>
    Colorez votre code PHP sur les forums grâce à Developpez.com



    Mise en aplication concrète de ce dont je te parle :
    article (id, date, author, title, text)
    keyword (id, name)
    article_keyword (#id_article, #id_keyword)
    Pour récupérer les mots clefs d'un article en particulier (dont tu as déjà l'identifiant) :
    <?php
    //
    // Requête
    //
    $sql = 'SELECT k.`name`
    &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FROM `keyword` AS k
    &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; INNER JOIN `article_keyword` AS ak ON ak.`id_keyword` = k.`id`
    &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; WHERE ak.`id_article` = '.$id_article.'
    &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ORDER BY k.`name`';

    $result = mysql_query($sql) or die(__LINE__.'<br />'.mysql_error());

    //
    // Récupération et affichage
    //
    while($keyword = mysql_fetch_assoc($result)){
    &#160;&#160;&#160; echo $keyword['name'].'<br />';
    }
    ?>
    Colorez votre code PHP sur les forums grâce à Developpez.com

  19. #19
    Membre averti Avatar de renaud26
    Homme Profil pro
    Webmaster
    Inscrit en
    Mars 2003
    Messages
    1 365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 365
    Points : 436
    Points
    436
    Par défaut
    Déjà merci à vous de se pencher sur mon prob. Sympa...Yogui, ton code affiche les mots clefs de toute la table mais non dédoublonnés. Je vais creuser ton idée de table.

    Maxoo, effectivement un array_merge par dessus le array_unique fonctionne bien. Reste que pour trier les données, j'ai tenté de glisser un sort() quelque part...sans succès jusqu'à présent: toujours des warnings de wrong parameters...

  20. #20
    Membre émérite

    Homme Profil pro
    Expert PHP
    Inscrit en
    Novembre 2004
    Messages
    2 127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Expert PHP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 127
    Points : 2 557
    Points
    2 557
    Par défaut
    ca marche pas ?

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. [AC-2003] Eviter Doublons Dans resultat requête
    Par rastaspilo dans le forum Requêtes et SQL.
    Réponses: 9
    Dernier message: 20/09/2009, 20h57
  2. Problème doublon dans fonction select
    Par roman67 dans le forum SQL
    Réponses: 10
    Dernier message: 31/07/2008, 13h09
  3. Eviter doublon dans une liste déroulante
    Par Joachim49 dans le forum Excel
    Réponses: 4
    Dernier message: 21/05/2007, 12h07
  4. Eviter doublon dans Requete Access 2000
    Par Soulama dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 21/02/2007, 10h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo