Précédent   Forum des professionnels en informatique > PHP > PHP & SGBD
PHP & SGBD Forum d'entraide sur les SGBD avec PHP. Avant de poster : FAQ BDD, toutes les FAQ PHP, cours BDD et sources BDD
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 05/07/2006, 18h25   #1
Membre confirmé
 
Avatar de renaud26
 
Inscription : mars 2003
Messages : 1 043
Détails du profil
Informations personnelles :
Âge : 48
Localisation : France, Puy de Dôme (Auvergne)

Informations forums :
Inscription : mars 2003
Messages : 1 043
Points : 285
Points : 285
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 ?
renaud26 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/07/2006, 18h35   #2
Expert Confirmé
 
Avatar de Eusebius
 
Inscription : avril 2003
Messages : 3 286
Détails du profil
Informations forums :
Inscription : avril 2003
Messages : 3 286
Points : 3 155
Points : 3 155
Montre-nous comment tu utilises DISTINCT
Eusebius est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/07/2006, 18h41   #3
Membre confirmé
 
Avatar de renaud26
 
Inscription : mars 2003
Messages : 1 043
Détails du profil
Informations personnelles :
Âge : 48
Localisation : France, Puy de Dôme (Auvergne)

Informations forums :
Inscription : mars 2003
Messages : 1 043
Points : 285
Points : 285
Code :
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
renaud26 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/07/2006, 18h55   #4
Expert Confirmé
 
Avatar de Eusebius
 
Inscription : avril 2003
Messages : 3 286
Détails du profil
Informations forums :
Inscription : avril 2003
Messages : 3 286
Points : 3 155
Points : 3 155
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.
Eusebius est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/07/2006, 19h11   #5
Membre confirmé
 
Avatar de renaud26
 
Inscription : mars 2003
Messages : 1 043
Détails du profil
Informations personnelles :
Âge : 48
Localisation : France, Puy de Dôme (Auvergne)

Informations forums :
Inscription : mars 2003
Messages : 1 043
Points : 285
Points : 285
ç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 ?
renaud26 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/07/2006, 19h27   #6
Expert Confirmé
 
Avatar de Eusebius
 
Inscription : avril 2003
Messages : 3 286
Détails du profil
Informations forums :
Inscription : avril 2003
Messages : 3 286
Points : 3 155
Points : 3 155
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.
Eusebius est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/07/2006, 19h39   #7
Expert Confirmé
 
Avatar de Maxoo
 
Maxime Pasquier
Expert PHP
Inscription : novembre 2004
Messages : 2 126
Détails du profil
Informations personnelles :
Nom : Maxime Pasquier
Âge : 28
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 126
Points : 2 602
Points : 2 602
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.
__________________
Pour une bien meilleur lisibilité, utilisez la balise [code], c'est le [#] dans votre éditeur.
Mon espace Développez : mes Créations.


Rencontre & Carte des Membres de Developpez.com, version 3.0
Maxoo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/07/2006, 19h41   #8
Membre confirmé
 
Avatar de renaud26
 
Inscription : mars 2003
Messages : 1 043
Détails du profil
Informations personnelles :
Âge : 48
Localisation : France, Puy de Dôme (Auvergne)

Informations forums :
Inscription : mars 2003
Messages : 1 043
Points : 285
Points : 285
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 ?
renaud26 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/07/2006, 19h45   #9
Expert Confirmé
 
Avatar de Eusebius
 
Inscription : avril 2003
Messages : 3 286
Détails du profil
Informations forums :
Inscription : avril 2003
Messages : 3 286
Points : 3 155
Points : 3 155
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 !
Eusebius est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/07/2006, 19h45   #10
Expert Confirmé
 
Avatar de Maxoo
 
Maxime Pasquier
Expert PHP
Inscription : novembre 2004
Messages : 2 126
Détails du profil
Informations personnelles :
Nom : Maxime Pasquier
Âge : 28
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 126
Points : 2 602
Points : 2 602
array_unique supprimes les doublons, tu as vu mon post ?

EDIT : exact Eusebius un petit explode quelque part
__________________
Pour une bien meilleur lisibilité, utilisez la balise [code], c'est le [#] dans votre éditeur.
Mon espace Développez : mes Créations.


Rencontre & Carte des Membres de Developpez.com, version 3.0
Maxoo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/07/2006, 16h10   #11
Membre à l'essai
 
Inscription : septembre 2003
Messages : 79
Détails du profil
Informations forums :
Inscription : septembre 2003
Messages : 79
Points : 24
Points : 24
peut etre aussi qq chose du genre :
Code :
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
lolodelp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/07/2006, 16h33   #12
Membre confirmé
 
Avatar de renaud26
 
Inscription : mars 2003
Messages : 1 043
Détails du profil
Informations personnelles :
Âge : 48
Localisation : France, Puy de Dôme (Auvergne)

Informations forums :
Inscription : mars 2003
Messages : 1 043
Points : 285
Points : 285
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...
renaud26 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/07/2006, 16h55   #13
Membre confirmé
 
Avatar de renaud26
 
Inscription : mars 2003
Messages : 1 043
Détails du profil
Informations personnelles :
Âge : 48
Localisation : France, Puy de Dôme (Auvergne)

Informations forums :
Inscription : mars 2003
Messages : 1 043
Points : 285
Points : 285
re,

Voici ce que j'ai fait

Code :
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"....
renaud26 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/07/2006, 16h58   #14
Expert Confirmé
 
Avatar de Maxoo
 
Maxime Pasquier
Expert PHP
Inscription : novembre 2004
Messages : 2 126
Détails du profil
Informations personnelles :
Nom : Maxime Pasquier
Âge : 28
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 126
Points : 2 602
Points : 2 602
Code :
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.
__________________
Pour une bien meilleur lisibilité, utilisez la balise [code], c'est le [#] dans votre éditeur.
Mon espace Développez : mes Créations.


Rencontre & Carte des Membres de Developpez.com, version 3.0
Maxoo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/07/2006, 11h30   #15
Membre confirmé
 
Avatar de renaud26
 
Inscription : mars 2003
Messages : 1 043
Détails du profil
Informations personnelles :
Âge : 48
Localisation : France, Puy de Dôme (Auvergne)

Informations forums :
Inscription : mars 2003
Messages : 1 043
Points : 285
Points : 285
Merci Maxoo, ta piste était bonnne...pour des questions de présentation, j'ai fait une boucle for plutôt que print_r:

Code :
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 ?
renaud26 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/07/2006, 13h43   #16
Expert Confirmé
 
Avatar de Maxoo
 
Maxime Pasquier
Expert PHP
Inscription : novembre 2004
Messages : 2 126
Détails du profil
Informations personnelles :
Nom : Maxime Pasquier
Âge : 28
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 126
Points : 2 602
Points : 2 602
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
Citation:
Si vous passez un seul tableau à cette fonction et qu'il a des indices numériques, les clés seront réindexées normalement.
__________________
Pour une bien meilleur lisibilité, utilisez la balise [code], c'est le [#] dans votre éditeur.
Mon espace Développez : mes Créations.


Rencontre & Carte des Membres de Developpez.com, version 3.0
Maxoo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/07/2006, 14h21   #17
Rédacteur
 
Avatar de Yogui
 
Homme Guillaume Rossolini
Directeur technique
Inscription : février 2004
Messages : 13 720
Détails du profil
Informations personnelles :
Nom : Homme Guillaume Rossolini
Localisation : France

Informations professionnelles :
Activité : Directeur technique

Informations forums :
Inscription : février 2004
Messages : 13 720
Points : 17 355
Points : 17 355
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 :
Citation:
<?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)){
   
//
   // Insertion seulement si absent : aucun doublon
   //
   
if(!in_array($keyword, $keywords)){
        
$keywords[] = $keyword['name'];
   }
}
sort($keywords); // Tri des données

//
// Affichage final
//
foreach($keywords as $keyword){
   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 :
Citation:
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) :
Citation:
<?php
//
// Requête
//
$sql = 'SELECT k.`name`
            FROM `keyword` AS k
            INNER JOIN `article_keyword` AS ak ON ak.`id_keyword` = k.`id`
            WHERE ak.`id_article` = '
.$id_article.'
            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)){
   echo $keyword['
name'].'<br />';
}
?>
Colorez votre code PHP sur les forums grâce à Developpez.com
__________________
Mes articles - Zend Certified Engineer (PHP + Zend Framework)
Ressources PHP - Ressources Zend Framework
Yogui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/07/2006, 14h23   #18
Rédacteur
 
Avatar de Yogui
 
Homme Guillaume Rossolini
Directeur technique
Inscription : février 2004
Messages : 13 720
Détails du profil
Informations personnelles :
Nom : Homme Guillaume Rossolini
Localisation : France

Informations professionnelles :
Activité : Directeur technique

Informations forums :
Inscription : février 2004
Messages : 13 720
Points : 17 355
Points : 17 355
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 :
Citation:
<?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)){
   
//
   // Insertion seulement si absent : aucun doublon
   //
   
if(!in_array($keyword['name'], $keywords)){
        
$keywords[] = $keyword['name'];
   }
}
sort($keywords); // Tri des données

//
// Affichage final
//
foreach($keywords as $keyword){
   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 :
Citation:
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) :
Citation:
<?php
//
// Requête
//
$sql = 'SELECT k.`name`
         FROM `keyword` AS k
         INNER JOIN `article_keyword` AS ak ON ak.`id_keyword` = k.`id`
         WHERE ak.`id_article` = '.$id_article.'
         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)){
    echo $keyword['name'].'<br />';
}
?>
Colorez votre code PHP sur les forums grâce à Developpez.com
__________________
Mes articles - Zend Certified Engineer (PHP + Zend Framework)
Ressources PHP - Ressources Zend Framework
Yogui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/07/2006, 16h00   #19
Membre confirmé
 
Avatar de renaud26
 
Inscription : mars 2003
Messages : 1 043
Détails du profil
Informations personnelles :
Âge : 48
Localisation : France, Puy de Dôme (Auvergne)

Informations forums :
Inscription : mars 2003
Messages : 1 043
Points : 285
Points : 285
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...
renaud26 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/07/2006, 16h06   #20
Expert Confirmé
 
Avatar de Maxoo
 
Maxime Pasquier
Expert PHP
Inscription : novembre 2004
Messages : 2 126
Détails du profil
Informations personnelles :
Nom : Maxime Pasquier
Âge : 28
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 126
Points : 2 602
Points : 2 602
ca marche pas ?
__________________
Pour une bien meilleur lisibilité, utilisez la balise [code], c'est le [#] dans votre éditeur.
Mon espace Développez : mes Créations.


Rencontre & Carte des Membres de Developpez.com, version 3.0
Maxoo est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 21h30.


 
 
 
 
Partenaires

Hébergement Web