Jointure dans table et doublons

Résolu
MissTortue - 20 janv. 2013 à 18:29
cs_Malkuth Messages postés 268 Date d'inscription samedi 22 février 2003 Statut Membre Dernière intervention 24 avril 2013 - 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,
A voir également:

3 réponses

cs_Malkuth Messages postés 268 Date d'inscription samedi 22 février 2003 Statut Membre Dernière intervention 24 avril 2013 4
22 janv. 2013 à 12:46
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 '
'; 
    } 
} 
3
Rejoignez-nous