PHP|Débutant :: Forums

Advertisement

Besoin d'aide ? N'hésitez pas, mais respectez les règles

Vous n'êtes pas identifié(e).

#1 26-01-2013 23:04:23

sylve
Membre
Inscription : 19-02-2011
Messages : 6

jointure union sur deux tables

Bonjour,
Je travaille sur deux tables indépendantes (rubriques et images) qui contiennent des informations différentes (avec un nombre de colonnes différent) mais qui ont des champs communs :
Le lien entre les deux tables se fait sur trois champs : 'ville' = 'img_ville', 'feuille' = 'img_feuille' ET 'point' = 'img_point'.
Je voudrais afficher pour une variable récupérée par $[get] les informations de la table "rubriques" et celles, quand elles existent, de la table "images" triées par date (que ce soit les dates de la table rubriques ou celles de la table images).


Je suis terriblement désolée mais je n'ai pas compris comment on colorise le code (j'ai bien conscience que ce n'est pas trop lisible) :
- la structure de la table RUBRIQUE:

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` enum('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`))

la structure de la table "IMAGES"  :

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`))

Bien sûr, il y a des dates dans la table rubriques qui ne correspondent pas à celles de la table images.

Les requêtes simples réalisées que sur l'une ou l'autre tables  fonctionnent très bien.
Mais je ne sais que d'abord afficher le texte puis les images. Or je voudrais pouvoir afficher les données texte et/ou images triées par dates.

J'ai essayé de faire une jointure externe entre les tables avec LEFT OUTER JOIN  :
les informations s'affichent, c'est-à-dire que la 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 les données sont démultipliées et on aboutit à un tas de doublons.

A priori, il faudrait utiliser la jointure UNION entre deux select (d'après ce que j'ai pu lire : elle permet de mettre deux tables bout à bout en éliminant systématiquement les doublons) mais je ne comprends pas comment ça marche :

Voici le code de la requête  (encore en m'excusant de ne pas savoir le mettre en couleur)

<?php
[b]$connect[/b] = mysql_connect($serveur,$user,$mpasse) or die('Erreur de connexion');
mysql_select_db($db, $connect) or die('Base inexistante');
//définition de la variable  javascript
$ville = $_GET['ville'];
$feuille = $_GET['feuille'];
$point = $_GET['sq'];
$connect = mysql_connect($serveur,$user,$mpasse) or die('Erreur de connexion');
mysql_select_db($db, $connect) or die('Base inexistante');
//Requête sur la table RUBRIQUES
$sql = "select theme, point, date, rubr_texte, rubr_ref FROM rubriques WHERE ville = '$ville' AND feuille ='$feuille' AND point='$point'
UNION
select img_num, img_point, img_theme, img_date, img_legende FROM images WHERE img_ville = '$ville' AND img_feuille ='$feuille' AND img_point='$point' ORDER BY date OR img_date"
;
$res = mysql_query($sql) or die('erreur : '.mysql_error());
$nbres = mysql_num_rows($res);//affichage des résultats
if ($nbres)
{
while($data = mysql_fetch_assoc($res))
// on fait une boucle qui va faire un tour pour chaque enregistrement
    {
    // on affiche les informations de l'enregistrement en cours
if ($data['img_date']==0)
     {
       echo '<td><font size="1" face="Verdana"><div align="justify"><b>['.$data['point'].']</b></font></div>';
     echo '<td><font size="1" face="Verdana"><div align="justify"><b>['.$data['theme'].']</b></font></div>';
     echo '<td><font size="1" face="Verdana"><div align="justify"><b>'.$data['date'].'</b></font></div>';
     echo '<td><font size="1" face="Verdana"><div align="justify">'.$data['rubr_texte'].'</font></div>';
     echo '<td><font size="1" face="Verdana"><div align="justify"><b>Références :</b></font></div>';
     echo '<td><font size="1" face="Verdana"><div align="justify">'.$data['rubr_ref'].'</font></div>';
     echo '<br>';
      echo '<br>';
     }
else
{
      echo '<td><font size="1" face="Verdana"><div align="justify"><b>['.$data['point'].']</b></font></div>';
     echo '<td><font size="1" face="Verdana"><div align="justify"><b>['.$data['theme'].']</b></font></div>';
     echo '<td><font size="1" face="Verdana"><div align="justify"><b>'.$data['date'].'</b></font></div>';
     echo '<td><font size="1" face="Verdana"><div align="justify">'.$data['rubr_texte'].'</font></div>';
     echo '<td><font size="1" face="Verdana"><div align="justify"><b>Références :</b></font></div>';
     echo '<td><font size="1" face="Verdana"><div align="justify">'.$data['rubr_ref'].'</font></div>';
     echo '<br>';
      echo '<td><font size="1" face="Verdana"><div align="justify"><b>['.$data['img_date'].']</b></font></div>';
    echo '<br>';
echo '<img src="/atlas/illustrations/'.$data['img_num'].'"></div> ';
echo '<td><font size="1" face="Verdana"><div align="justify">'.$data['img_legende'].'</font></div>';
echo '<br>';
echo '<br>';
 }
}
}
        exit();
mysql_close($connect); //on ferme la connection à mysql
?>

Diverses tentatives dont la dernière qui a affiché le message suivant "The used SELECT statements have a different number of columns"
ont fait que j'ai renommé les titres des champs de la table IMAGES (c'est ceux qui sont dans la requête ci-dessus) et maintenant j'arrive à cela :


'.$data['point'].']
'; echo '
['.$data['theme'].']
'; echo '
'.$data['date'].'
'; echo '
'.$data['rubr_texte'].'
'; echo '
Références :
'; echo '
'.$data['rubr_ref'].'
'; echo '
'; echo '
'; } else { echo '
['.$data['point'].']
'; echo '
['.$data['theme'].']
'; echo '
'.$data['date'].'
'; echo '
'.$data['rubr_texte'].'
'; echo '
Références :
'; echo '
'.$data['rubr_ref'].'
'; echo '
'; echo '
['.$data['img_date'].']
'; echo '
'; echo ' '; echo '
'.$data['img_legende'].'
'; echo '
'; echo '
'; } } } exit(); mysql_close($connect); //on ferme la connection à mysql ?>

Donc maintenant, je pense que c'est un problème d'affichage des données issues des tables mais bon, je suis nulle !

Merci par avance de m'aider à comprendre ou, en tout cas, de m'indiquer où je pourrais trouver des articles plus explicites que ceux j'ai déjà pu consulter.

Hors ligne

#2 27-01-2013 22:29:04

Maljuna Kris
Infantimigulo
Lieu : Douarnenez 29100 Breizh Izel
Inscription : 08-05-2009
Messages : 2 453
Site Web

Re : jointure union sur deux tables

Saluton,
Avant de se pencher sur l'exploitation de la requête en PHP, on va d'abord essayer d'y voir plus clair avec le relationnel de tes deux tables.

Sylve a écrit :

Le lien entre les deux tables se fait sur trois champs : 'ville' = 'img_ville', 'feuille' = 'img_feuille' ET 'point' = 'img_point'.
Je voudrais afficher pour une variable récupérée par $[get] les informations de la table "rubriques" et celles, quand elles existent, de la table "images" triées par date (que ce soit les dates de la table rubriques ou celles de la table images).

Juste en passant, les champs sont dans les formulaires (ou à la campagne) dans les tables il y a des lignes de colonnes.
De deux phrases de ton énoncé initial je déduis (détrompe-moi le cas échéant) que toute ligne de la table images a forcément une correspondance dans la table rubrique, mais que certaines rubriques n'ont pas d'images en correspondance.
Peut-on affirmer que la relation est de type 1,0<=>1,1 , c'est à dire qu'à une rubrique ne correspond qu'une image au plus, et à une image correspond toujours une rubrique et une seule ?
De la réponse à cette question dépendra le type de jointure à réaliser.
Je puis tout de suite te dire que la requête UNION ne me semble pas du tout adaptée.


Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy

Hors ligne

#3 27-01-2013 23:13:42

sylve
Membre
Inscription : 19-02-2011
Messages : 6

Re : jointure union sur deux tables

Bonjour,
A la question

Peut-on affirmer que la relation est de type 1,0<=>1,1 , c'est à dire qu'à une rubrique ne correspond qu'une image au plus, et à une image correspond toujours une rubrique et une seule ?

la réponse est non.

A un point [x] est toujours associée au moins une rubrique (= 1 date) mais pas forcément une image. Pour ce point [x], il peut y avoir une ou plusieurs images (avec une date qui peut ou pas correspondre à celle de la rubrique ou plusieurs dates).
Par exemple,
pour un point [1], il y a 5 dates de rubriques et aucune image
pour le point [2], il y a une date de rubrique et une date pour une image mais ce ne sont pas les mêmes dates
pour le point [3],  il y deux dates de rubriques et une date pour une image (qui est différente des deux dates de rubriques)
pour le point [4], trois dates de rubrique et 10 dates d'images (les dates de la rubrique peuvent être différentes  de toutes les dates d'image mais il peut y avoir une date de rubrique qui correspond à une ou plusieurs dates d'images)
etc.
C'est le point [x] qui fait le lien entre les deux tables.
Je ne sais pas si c'est très clair.

Peut-être aurais-je dû concevoir qu'une seule table et n'extraire que les informations pour les afficher au moyen d'un if et les trier par date ?

Hors ligne

#4 27-01-2013 23:55:06

Maljuna Kris
Infantimigulo
Lieu : Douarnenez 29100 Breizh Izel
Inscription : 08-05-2009
Messages : 2 453
Site Web

Re : jointure union sur deux tables

Tu as un problème relationnel entre ces deux tables. Deux rubriques (voire davantage) pouvant pointer sur le même point de la même feuille de la même ville, comment savoir à quelle rubrique rattacher une image ?
Il faudrait que l'id de la rubrique soit contenue dans la table image.
Ou alors je n'ai rien compris.


Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy

Hors ligne

#5 28-01-2013 09:54:38

sylve
Membre
Inscription : 19-02-2011
Messages : 6

Re : jointure union sur deux tables

Bonjour,
Voici la structure des deux tables sous la forme d'une image et leurs liens :
structures table
Les informations contenues dans la table Rubriques ne sont pas les mêmes que dans la table Images.

Hors ligne

#6 28-01-2013 11:51:46

Maljuna Kris
Infantimigulo
Lieu : Douarnenez 29100 Breizh Izel
Inscription : 08-05-2009
Messages : 2 453
Site Web

Re : jointure union sur deux tables

Désolé mais, apparemment, tu nous a fourni une image qui requiert un mot de passe pour y accéder, ce qui fait qu'on ne peut pas la voir.
Décidément, LVNES [La Vivo Ne Estas Simpla]. wink


Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy

Hors ligne

#7 28-01-2013 12:34:31

sylve
Membre
Inscription : 19-02-2011
Messages : 6

Re : jointure union sur deux tables

Oui je suis d'accord, LVNES
Bon comme je ne sais pas où mettre cette image, je vais essayer de faire quelque chose ci-dessous
Table Rubriques                                    Table Images
id_rubr                                                img_id
ville     ------------------------------>   img_ville
feuille  ------------------------------>   img_feuille
point   ------------------------------>   img_point
theme                                                img_theme
date                                                  img_date
rubr_texte                                          img_num 
rubr_ref                                             img_legende

les id sont en auto_increment.

Les flèches indiquent les liens entre les colonnes (strictement identique).


Je veux juste pouvoir afficher par ordre chronologique (tri sur "date") les informations de la table Rubriques et celles de la table Images.

Hors ligne

#8 28-01-2013 15:03:42

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : jointure union sur deux tables

Bonjour,

En général, lorsque l'on répond en bon Français à nos questions, on est capable de comprendre du premier coup la réponse, en toute amitié wink

Si tu répondais à la question pertinente de MK à savoir

Maljuna Kris a écrit :

comment savoir à quelle rubrique rattacher une image ?

Cela permettrait d'avancer un tant soit peu.

Bonne journée wink

Dernière modification par Jc (28-01-2013 15:04:41)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#9 28-01-2013 20:45:00

sylve
Membre
Inscription : 19-02-2011
Messages : 6

Re : jointure union sur deux tables

On ne peut pas savoir.
Les dates des rubriques et des images peuvent concorder. Mais les dates des images peuvent être aussi différentes et venir en complément d'une rubrique.


Par exemple :
pour le point [3], je vais afficher les rubriques :


[3]
[voirie]
1828-1829
Ch. Texier indique qu’« une fouille faite … au devant de la porte des Gaules, a mis à découvert le prolongement de la voie, construit ainsi qu’il a été dit ci-dessus », c’est-à-dire avec « une surface composée de chaux blanche et de briques concassées ».
Références :
- TEXIER (Ch.), Mémoires sur la ville et le port de Fréjus, dans Mémoires présentés par divers savants à l’Académie des Inscriptions et Belles-Lettres de l’Institut National de France, 2e série, II, Paris, 1849, p. 254.


[3]
1919-1921
Mêmes conditions que [2]. Immédiatement à l’extérieur de la Porte des Gaules, J. Formigé trouve, sous le niveau mis au jour par Ch. Texier, un « dallage avec les parties usées par les roues des véhicules ». Dans une publication ultérieure, il précise qu’il s’agit d’« une partie de pavage en forte pente, avec de profondes ornières ».
Références :
- FORMIGÉ (J.), Communication sur les fouilles des Portes décumanes et du théâtre, dans Bulletin de la Société Nationale des Antiquaires de France, 1921 (séance du 2 mars), p. 127.
- FORMIGÉ (J.), Fréjus, Forum Julii Octavanorum Colonia, dans Congrès archéologique de France, Aix-en-Provence et Nice (1932), Paris, 1933, p. 252.


[3]
1938
Mêmes conditions que [2]. A. Donnadieu considère, dans sa publication sur les portes de Fréjus, que la Porte des Gaules donne le passage au decumanus maximus sur une largeur de 5,25 m et qu’il « était prolongé au-delà de la Porte par une voie romaine reconnue par Charles Texier » dont il ne « reste plus que les assises inférieures, la chaussée proprement dite ayant été usée et non refaite. Les pierres qu’on aperçoit, en effet, sur la photographie [non présentée ici] sont à un niveau inférieur à celui de la Porte ». Il s’agit du dallage découvert par J. Formigé.
Références :
- DONNADIEU (A.), Les Portes du « Decumanus Maximus » de la « Colonia Octavanorum » au « Forum Julii » (Fréjus-Var), dans Bulletin de la Société d’Etudes Scientifiques et Archéologiques de Draguignan, XLII, 1938-1939, 2e partie, Mémoires LII, 1938, p. 37.


[3]
vers 1970
Dans les années 1970, un jardinier récupère un as coupé de Tibère (RIC I2, no 91 et suiv.), daté de 14-37, en désherbant entre les pierres du dallage.
Références :
- Information xx.

etc.


Pour la table IMAGES


[3]
[1920]
img001.png
Légende : La Porte des Gaules [2] et la voie dallée [3] (dessin anonyme, 1920).

[3]
[Vers 1970]
img002.png
Légende : la monnaie (cliché CNRS-CCJ no 51000).


[3]
[1975]
img003.png
Légende : A l'extérieur de la Porte des Gaules [2], la voie dallée [3], vue du sud-ouest (cliché CNRS-CCJ no 87369).


[3]
[1980]
img004.png
Légende : La Porte des Gaules [2] vue du sud et, dans l'axe, les restes du dallage de la voie [3] (cliché xx, 1975).

etc.

Donc ce sont des tables qui sont relativement indépendantes, qui ne contiennent pas le même genre de données.
Actuellement j'affiche toutes les informations relatives à un point, rubriques et images (mais d'abord les rubriques, puis les images), mais j'aurais préféré que ces informations s'affichent par ordre chronologique :


[3]
[voirie]
1828-1829
Ch. Texier indique qu’« une fouille faite … au devant de la porte des Gaules, a mis à découvert le prolongement de la voie, construit ainsi qu’il a été dit ci-dessus », c’est-à-dire avec « une surface composée de chaux blanche et de briques concassées ».
Références :
- TEXIER (Ch.), Mémoires sur la ville et le port de Fréjus, dans Mémoires présentés par divers savants à l’Académie des Inscriptions et Belles-Lettres de l’Institut National de France, 2e série, II, Paris, 1849, p. 254.


[3]
1919-1921
Mêmes conditions que [2]. Immédiatement à l’extérieur de la Porte des Gaules, J. Formigé trouve, sous le niveau mis au jour par Ch. Texier, un « dallage avec les parties usées par les roues des véhicules ». Dans une publication ultérieure, il précise qu’il s’agit d’« une partie de pavage en forte pente, avec de profondes ornières ».
Références :
- FORMIGÉ (J.), Communication sur les fouilles des Portes décumanes et du théâtre, dans Bulletin de la Société Nationale des Antiquaires de France, 1921 (séance du 2 mars), p. 127.
- FORMIGÉ (J.), Fréjus, Forum Julii Octavanorum Colonia, dans Congrès archéologique de France, Aix-en-Provence et Nice (1932), Paris, 1933, p. 252.


[3]
[1920]
img001.png
Légende : La Porte des Gaules [2] et la voie dallée [3] (dessin anonyme, 1920).

[3]
1938
Mêmes conditions que [2]. A. Donnadieu considère, dans sa publication sur les portes de Fréjus, que la Porte des Gaules donne le passage au decumanus maximus sur une largeur de 5,25 m et qu’il « était prolongé au-delà de la Porte par une voie romaine reconnue par Charles Texier » dont il ne « reste plus que les assises inférieures, la chaussée proprement dite ayant été usée et non refaite. Les pierres qu’on aperçoit, en effet, sur la photographie [non présentée ici] sont à un niveau inférieur à celui de la Porte ». Il s’agit du dallage découvert par J. Formigé.
Références :
- DONNADIEU (A.), Les Portes du « Decumanus Maximus » de la « Colonia Octavanorum » au « Forum Julii » (Fréjus-Var), dans Bulletin de la Société d’Etudes Scientifiques et Archéologiques de Draguignan, XLII, 1938-1939, 2e partie, Mémoires LII, 1938, p. 37.


[3]
vers 1970
Dans les années 1970, un jardinier récupère un as coupé de Tibère (RIC I2, no 91 et suiv.), daté de 14-37, en désherbant entre les pierres du dallage.
Références :
- Information xx.

[3]
[Vers 1970]
img002.png
Légende : La monnaie (cliché CNRS-CCJ no 51000).

[3]
[1975]
img003.png
Légende : A l'extérieur de la Porte des Gaules [2], la voie dallée [3], vue du sud-ouest (cliché CNRS-CCJ no 87369).

[3]
[1980]
img004.png
Légende : La Porte des Gaules [2] vue du sud et, dans l'axe, les restes du dallage de la voie [3] (cliché xx, 1975).

J'espère qu'avec cet exemple, vous aurez compris que c'est le "point" d'une feuille dans une ville donnée qui est le fil conducteur.

Maintenant, peut-être que la base est mal conçue, peut-être qu'il ne s'agit que d'un problème de requête imbriquée ou d'un problème d'affichage ?
Je pensais qu'une jointure pouvait être la solution.

Hors ligne

#10 28-01-2013 22:00:45

Maljuna Kris
Infantimigulo
Lieu : Douarnenez 29100 Breizh Izel
Inscription : 08-05-2009
Messages : 2 453
Site Web

Re : jointure union sur deux tables

Les colonnes qui doivent permettre de faire les jointures devraient être des clés numériques (clés étrangères en outre, apparemment) pour les colonnes ville, feuille et point. De même les colonnes contenant des dates devraient être de type DATE.
Tout cela pour espérer un minimum de performance.
Tu devrais avoir une table villes, une table feuilles et une table points comme cela chacune intégrant la clé étrangère de son parent comme index UNIQUE (une feuille n'appartenant qu'à une ville, un point n'appartenant qu'à une feuille) comme cela tu n'aurais plus qu'à mettre l'identifiant du point comme clé étrangère dans les tables rubriques et images. L'écriture de ta jointure serait simplifiée.
Maintenant, s'agissant de la jointure, la question resterait posée, comment savoir quelle rubrique pointant sur le point[3] est à mettre en relation avec chacune des images pointant sur le même point, ou inversement ?


Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy

Hors ligne

#11 29-01-2013 09:32:02

sylve
Membre
Inscription : 19-02-2011
Messages : 6

Re : jointure union sur deux tables

Bonjour à tous,
Si je comprends bien, c'est ma BDD qui est mal conçue.
Pour la documentation de base que je dois intégrer à la BDD :
Chaque ville a un découpage en feuilles numérotées de 1 à n mais chaque ville n'a pas le même nombre de feuilles.
Chaque feuille comporte un certain nombre de points numérotés de 1 à n mais chaque feuille n'a pas le même nombre de points.
Pour chaque point, il y a une ou des rubriques de texte (classées par dates) ET/OU pas, ou une, ou des images (classées également par date).

Je vais réfléchir à tout cela et reviendrai vers vous.

Bonne journée

Hors ligne

Pied de page des forums