Jointure dans table et doublons [Résolu]

MissTortue - 20 janv. 2013 à 18:29 - Dernière réponse : cs_Malkuth 278 Messages postés samedi 22 février 2003Date d'inscription 24 avril 2013 Dernière intervention
- 22 janv. 2013 à 12:46
Bonjour
J'ai deux tables ("rubriques" et images") que j'ai liées par une jointure externe. J'arrive à récupérer toutes les informations pour pouvoir les afficher dans une page de résultats mais avec en doublonnant au maximum. Je me rends bien compte que c'est un problème de syntaxe dans la requête ; si je fais des requêtes simples sur chaque table, tout marche bien et les informations arrivent aussi quand je fais des essais sur les deux tables avec la jointure mais les résultats pour chaque ligne s'affichent en double, triple, quadruple, etc.
J'ai bien lu les tutoriaux sur les jointures, essayé tous les types de jointures externes mais rien n'y fait.


Voici mon code :
//définition de la variable javascript
$ville = $_GET['ville'];
$feuille = $_GET['feuille'];
$point = $_GET['sq'];
//connexion BDD
$connect = mysql_connect($serveur,$user,$mpasse) or die('Erreur de connexion');
mysql_select_db($db, $connect) or die('Base inexistante');
//Requête sur les table RUBRIQUES et IMAGES
$sql "select DISTINCT * FROM rubriques LEFT OUTER JOIN images on rubr_point img_point and ville = img_ville and feuille = img_feuille WHERE ville = '$ville' AND feuille ='$feuille' AND rubr_point='$point' ORDER BY rubr_point AND rubr_date OR img_point AND img_date" ;
$res = mysql_query($sql) or die('erreur : '.mysql_error());
$nbres = mysql_num_rows($res);//affichage des résultats
{
while($data = mysql_fetch_assoc($res))
// on fait une boucle qui va faire un tour pour chaque enregistrement
{
if ($data['rubr_point']==$data['img_point'])
// on affiche les informations de l'enregistrement en cours
echo '<td>
['.$data['rubr_point'].']
';
echo '<td>
'.$data['rubr_date'].'
';
echo '<td>
'.$data['rubr_texte'].'
';
echo '<td>
Références :
';
echo '<td>
'.$data['rubr_ref'].'
';
echo '
';
echo '<td>
'.$data['img_date'].'
';
echo '<td>
'.$data['img_legende'].'
';
echo '
';
echo '
';
}
}
exit();


En vous remerciant par avance,
Afficher la suite 

Votre réponse

3 réponses

Meilleure réponse
cs_Malkuth 278 Messages postés samedi 22 février 2003Date d'inscription 24 avril 2013 Dernière intervention - 22 janv. 2013 à 12:46
3
Merci
si j'ai bien compris en définitive, tes 2 table sont indépendantes MAIS on toutes deux Rapport à un même éléments extérieur et ce que tu voudrais est le résultat en une seule requette de tes deux requettes.

Pour celà, une jointure n'est pas la solution, une jointure sert à entreméllé des table dans un même résultat.

Example avec des table simple

Table T_A
A_1    A_2
1      1    (LA1)
1      2    (LA2)

Table T_B
B_1    B_2
1      2    (LB1)
2      2    (LB2)


CROSS JOIN = > SELECT * FROM T_A,T_B
On mélange tout avec tout :
A_1    A_2    B_1    B_2
1      1      1      2      (LA1 + LB1)
1      2      1      2      (LA2 + LB1)
1      1      2      2      (LA1 + LB2)
1      2      2      2      (LA2 + LB2)


On vois clairement que certaines données sont dupliqué car participe à plusieurs "mélanges"

INNER JOIN => SELECT * FROM T_A INNER JOIN T_B ON A_2 = B_2
On mélange tout avec tout et on ne garde que les résultats qui satisfont le prédicat de jointure :
A_1    A_2    B_1    B_2
1      2      1      2      (LA2 + LB1)
1      2      2      2      (LA2 + LB2)


(LA1 + LB1) et (LA1 + LB2) ne satisfont pas le prédicat et sont donc écartés.
On remarque que certaines données peuvent toujours apparaitrent en doublons

OUTER JOIN => SELECT * FROM T_A LEFT OUTER JOIN T_B ON A_2 = B_2
On mélange tout avec tout et on ne garde que les résultats qui satisfont le prédicat de jointure ensuite on rajoute les lignes de la table de gauche qui n'apparaissent pas dans le résultat:
A_1    A_2    B_1    B_2
1      2      1      2      (LA2 + LB1)
1      2      2      2      (LA2 + LB2)
1      1      NULL   NULL   (LA1 + NULL)


ici, LA11 ne correspond a aucun mélange possible, il est donc introduit dans le résultat sans correspondance dans la table T_B.
On as toujours répétitions des données lorsqu'elle participent à plusieurs "mélanges".

Revenons à ton code, tu est dans le dernier cas de figure, tel que tu t'y prend, tu ne pourras pas évité les doublons avec une jointure.

la voie a suivre est plutôt celle de l'UNION qui permets de réunir le résultat de 2 requette distincte sous certaines conditions. cest conditions sont que les diférente requettes doivent avoir la même forme de résultat : même nombre et même type de colone... dans ton cas il va faloir rusé :

requette 1 :

SELECT 'est_rubr', 'point', 'date', 'texte', 'ref'
FROM (
    SELECT (1) 'est_rubr', ('rubr_point') 'point', ('rubr_date') 'date', ('rubr_texte') 'texte', ('rubr_ref') 'ref'
    FROM 'rubriques' 
    WHERE 'ville' '$ville' AND 'feuille''$feuille' AND 'rubr_point'='$point'

    UNION

    SELECT (0) 'est_rubr', ('img_point') 'point', ('img_date') 'date', ('img_legende') 'texte', ('img_num') 'ref'
    FROM 'images' 
    WHERE 'img_ville' '$ville' AND 'img_feuille''$feuille' AND 'img_point'='$point'
) 'Source'
ORDER BY 'point' AND 'date'


Dans ton code, tu devras vérifiez la valeur du champ 'est_rubr'(1=>rubrique, 0=>image) puis en fonction, utilisé les autres champs pour ton affichage :
while($data = mysql_fetch_assoc($res)) 
// on fait une boucle qui va faire un tour pour chaque enregistrement 
{ 
    if ($data['est_rubr']==1)
    { 
    // on affiche une rubrique
        echo '<td>
['.$data['point'].']
'; 
        echo '<td>
'.$data['date'].'
'; 
        echo '<td>
'.$data['texte'].'
'; 
        echo '<td>
Références :
'; 
        echo '<td>
'.$data['ref'].'
'; 
        echo '
'; 
    }
    else
    {
    // on affiche une image
        echo '<td>
'.$data['date'].'
'; 
        echo '<td>
'.$data['texte'].'
'; 
        echo '
 '; 
        echo '
'; 
    } 
} 

Merci cs_Malkuth 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 92 internautes ce mois-ci

Commenter la réponse de cs_Malkuth
cs_Malkuth 278 Messages postés samedi 22 février 2003Date d'inscription 24 avril 2013 Dernière intervention - 20 janv. 2013 à 22:46
0
Merci
oulà!
Tu peux nous mettre la description des table et nous extraire la requête effectué et ensuite nous expliquer ce que tu as comme résultat et se que tu aurais voulu.
Commenter la réponse de cs_Malkuth
MissTortue - 22 janv. 2013 à 10:02
0
Merci
Bonjour,
Il y a une table "RUBRIQUES" dont voici la structure :

CREATE TABLE IF NOT EXISTS `rubriques` (`id` int(4) NOT NULL AUTO_INCREMENT, `ville` enum('xx','yy')
NOT NULL DEFAULT 'Aix-en-Provence', `feuille` enum('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15')
NOT NULL DEFAULT '1', `theme` num('enceinte','voirie','hydraulique','public','habitat','artisanat','necropole','port','camp','divers') NOT NULL DEFAULT 'enceinte', `rubr_point` varchar(4) NOT NULL DEFAULT '', `rubr_date` varchar(30) NOT NULL DEFAULT '',
`rubr_texte` longtext NOT NULL, `rubr_ref` mediumtext NOT NULL,
PRIMARY KEY (`id`))

Il y a une autre table "IMAGES" dont voici la structure :

CREATE TABLE IF NOT EXISTS `images` (
`id_img` int(5) NOT NULL AUTO_INCREMENT,
`img_ville` enum('xx','yy') NOT NULL DEFAULT 'Aix-en-Provence',
`img_num` varchar(15) NOT NULL DEFAULT '',
`img_feuille` enum('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15') NOT NULL DEFAULT '1',
`img_point` varchar(4) NOT NULL DEFAULT '',
`img_date` varchar(20) NOT NULL DEFAULT '',
`img_theme` enum('enceinte','voirie','hydraulique','public','habitat','artisanat','necropole','port','camp') NOT NULL DEFAULT 'enceinte',
`img_legende` mediumtext NOT NULL,
PRIMARY KEY (`id_img`))

Le lien entre les deux se fait sur deux champs : 'rubr_ville' 'img_ville' ET 'rubr_point' 'img_point'.
L'idée c'est que – précisons que je suis archéologue et que je ne pas super douée en programmation – pour un point de la carte sont associées x rubriques de texte correspondant à x dates de travaux sur ce point pour la Table "rubriques" et à x images (dont les dates sont différentes) pour la Table "images".

Sur le site que je souhaite créer, il y a une carte et sur cette carte, des zones réactives qui permettent de récupérer une variable javascript.
Lorsqu'on clique sur un point, je voudrais que les informations issues des tables "rubriques" et "images" s'affichent.
Le procédé marche très bien si la requête n'est réalisée que sur l'une ou l'autre table (par exemple sur la table "rubriques" $sql "select * FROM rubriques WHERE ville '$ville' AND feuille ='$feuille' AND rubr_point='$point' ORDER BY rubr_point AND rubr_date" ; fonctionne très bien).
En revanche, dès que je veux interroger les deux tables ensembles, il y a un problème de doublons, c'est-à-dire que les informations s'affichent en multipliées x fois suivant le nombre d'enregistrement du point.
Mais les informations s'affichent, c'est-à-dire que le variable est bien reconnue et que la requête ($sql "select DISTINCT * FROM rubriques LEFT OUTER JOIN images on rubr_point img_point and ville = img_ville and feuille = img_feuille WHERE ville = '$ville' AND feuille ='$feuille' AND rubr_point='$point' ORDER BY rubr_point") fonctionne mais avec des doublons.
Je ne sais pas si je me suis bien exprimée mais j'espère que quelqu'un pourra m'expliquer où est le problème dans la jointure ou dans la récupération des données.
Merci par avance
Commenter la réponse de MissTortue

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.