MissTortue
-
20 janv. 2013 à 18:29
cs_Malkuth
Messages postés268Date d'inscriptionsamedi 22 février 2003StatutMembreDernière intervention24 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();
cs_Malkuth
Messages postés268Date d'inscriptionsamedi 22 février 2003StatutMembreDernière intervention24 avril 20134 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.
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 :
(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:
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 '
';
}
}
cs_Malkuth
Messages postés268Date d'inscriptionsamedi 22 février 2003StatutMembreDernière intervention24 avril 20134 20 janv. 2013 à 22:46
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.
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