Page 1 sur 1
jointure simple
Posté : 21 mars 2021, 02:22
par claude99
Bonjour,
J'ai une jointure toute simple concernant 2 tables qui ont les mêmes noms de champs et dont le contenu du champ "num" est identique (champ incrémenté). Le nombre d'enregistrements est le même. Je voudrais comparer les valeurs d'un des autres champs nommé aei. Les tables sont nommées table1 et table2.
Voilà mon code:
$query="SELECT * FROM table1
FULL JOIN table2
ON table1.num=table2.num;";
$res=$bdd->query($query);
while($ligne=$res->fetch())
{
$aei1=$ligne[table1.aei];
$aei2=$ligne[table2.aei];
echo "<br>",$aei1," ",$aei2;
}
J'obtiens l'erreur:
Fatal error: Uncaught Error: Call to a member function fetch() on bool in...
Re: jointure simple
Posté : 21 mars 2021, 14:37
par or 1
ce message veut dire que
$bdd->query($query) a retourné false, peut-être à cause du ;
Re: jointure simple
Posté : 21 mars 2021, 17:14
par claude99
Il faut forcément un ; après la commande
$res=$bdd->query($query);
Donc, je ne comprends toujours pas
Re: jointure simple
Posté : 21 mars 2021, 21:39
par Saian
Salut, or 1 parlait du point virgule de la requête sql.
Le message d'erreur dit que tu appelles la méthode fetch sur un booléen. $res est donc un booléen et ceci se produit quand il y a une erreur avec la requête et que la méthode query retourne false (un booléen).
Utilises la méthode errorInfo pour savoir quelle est l'erreur.
https://www.php.net/manual/fr/pdo.query.php
https://www.php.net/manual/fr/pdo.errorinfo.php
Re: jointure simple
Posté : 22 mars 2021, 12:35
par claude99
Merci pour les liens qui sont certainement pertinents., mais j'avoue éprouver des difficultés à les décrypter pour trouver la solution. Il me semble que PHP sur cette requête ne parvient pas à différentier les 2 tables. En effet, tous les champs ont même nom, la différence est uniquement le contenu des enregistrements. Je vais essayer de modifier les noms des champs pour voir si cela résout le problème.
Re: jointure simple
Posté : 22 mars 2021, 16:19
par Ryle
Salutations !
Le problème ne vient pas du fait que tes colonnes aient le même nom dans les deux tables, mais du fait qu'à priori, le moteur de MySQL ne connait pas l'instruction FULL JOIN. Tu peux simuler celui-ci en faisant une UNION entre deux requêtes faisant respectivement un LEFT JOIN et un RIGHT JOIN
Tu peux essayer d'exécuter ta requête directement dans phpMyAdmin pour voir le message d'erreur (Erreur de syntaxe près de 'full join...')
Re: jointure simple
Posté : 22 mars 2021, 18:22
par claude99
Merci pour ces suggestions. FULL JOIN effectivement ne fonctionne pas, mais dans ce cas UNION ne me paraît pas possible car le contenu du champ d'identification incrémenté (ici num) a même contenu pour les 2 tables, seul le contenu des autres champ est différent.
En tâtonnant, j'ai réussi à obtenir le résultat de la jointure par les opérations suivantes:
-J'ai renommé tous les champs de table2 d'un nom différent de ceux de table1 (en l'occurrence en ajoutant le chiffre 2, soit par exemple aei dans table1 et aei2 dans table2, num dans table1 et num2 dans table2)
-j'ai remplacé FULL par INNER (ou par rien ça fonctionne aussi). (les 2 tables ayant les même valeurs dans le champ d'identification, ça se comprend que FULL équivaille à INNER dans ce cas)
Ces 2 conditions sont nécessaires, du moins je n'ai pas réussi autrement:
soit:
$query="SELECT * FROM table1 INNER JOIN table2 ON
table1.num=table2.num2;";
$res=$bdd->query($query);
$ligne=$res->fetch();
$aei=$ligne['aei'];
$aei2=$ligne['aei2'];
echo "<br>",$aei," ",$aei2,"<br>";
Remarque: les expressions suivantes ne fonctionnent pas (elles sont d'ailleurs inutiles dans ce cas)
$aei1=ligne['table1.aei'];
$aei2=ligne['table2.aei2'];
C'est le même problème avec la formulation suivante équivalant à FULL JOIN si les champs ont des noms identiques:
$query="SELECT * FROM table1,table2 WHERE num=num2;";
$res=$bdd->query($query);
$ligne=$res->fetch();
$aei=$ligne['aei'];
$aei2=$ligne['aei2'];
echo "<br>",$aei," ",$aei2,"<br>";
Si les champs ont des noms différents, ça fonctionne.
On remarquera que pour le WHERE la formulation
table1.num=table2.num2
ne fonctionne pas, mais la formulation
num=num2
fonctionne, et elle est effectivement suffisante.
Re: jointure simple
Posté : 22 mars 2021, 18:52
par claude99
Pour terminer, je remarque que les champs correspondant d'identification incrémentés de la rubrique ON peuvent avoir effectivement le même nom (par exemple ici num), ils se différencient en effet dans la requête par:
ON table1.num=table2.num
mais les autres champs, d'après mes essais doivent avoir un nom différent, en tout cas, je n'ai pas réussi autrement.
Re: jointure simple
Posté : 22 mars 2021, 21:11
par Ryle
Tu peux tout à fait avoir les mêmes nom de champ dans les deux tables, cela ne pose pas de problème pour ta requête SQL (tu peux même faire des jointures d'une table sur elle même, dans le genre on garde les mêmes noms, on peut pas faire mieux

)
Le problème que tu rencontres ensuite est dans la façon dont php va traiter et lire les enregistrements et c'est là où il ne saura pas les distinguer si tu fais un "SELECT * ". Il ne récupère pas les noms des tables pour construire ses index et n'aura donc qu'une seule colonne pour deux valeurs.
La première solution serait que dans les options de ton fetch() tu forces les indexes numériques plutôt que (ou en plus) associatif (y a un paramètre PDO qui fait ça). Tu auras alors accès à la colonne 1, la colonne 2, etc. plutôt que la colonne "aei". Ça fonctionne, mais c'est pas vraiment simple à gérer et encore moins à maintenir.
Le mieux, tant pour la lecture, le traitement, la maintenance, etc. c'est de lister les champs que tu récupères dans le SELECT, et d'en profiter pour donner des alias (plutôt que de renommer physiquement tes colonnes en base).
Tu peux ainsi faire un "SELECT table1.num, table1.aei, ... , table2.num as num2, table2.aei as aei2 ... FROM". Et tu pourras alors en php aller lire la valeur de ligne['aei'] qui te retournera la valeur de la colonne dans la table 1 et ligne['aei2'] qui te retournera celle de la table 2

Re: jointure simple
Posté : 22 mars 2021, 23:35
par claude99
Merci pour ta réponse très documentée et pour les solutions.Je me doutais que php ne récupérait pas les noms des tables et ne pouvait donc les différencier. La solution des alias est intéressante si on a de nombreuses tables dans ce cas de figure et moins de requêtes. En revanche, si on a un grand nombre de requêtes et un moins grand nombre de tables, il vaut mieux renommer les champs. Le problème, c'est qu'on a souvent un grand nombre de tables et un grand nombre de requêtes
