Requête SQL 2 tables

Signaler
-
 omlaly -
Bonjour,

Je cherche à sélectionner les commentaires de l'article correspondant.

Voici les CREATE TABLE des 2 tables :
ARTICLES :
CREATE TABLE IF NOT EXISTS `articles` (
  `id_article` int(11) NOT NULL AUTO_INCREMENT,
  `nom_village` varchar(255) CHARACTER SET latin1 NOT NULL,
  `nom_categorie` varchar(255) CHARACTER SET latin1 NOT NULL,
  `date_depot` datetime NOT NULL,
  `titre_article` varchar(255) NOT NULL,
  `texte_article` text NOT NULL,
  `auteur_article` varchar(255) NOT NULL,
  PRIMARY KEY (`id_article`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=80 ;


COMMENTAIRES :
CREATE TABLE IF NOT EXISTS `commentaires` (
  `id_commentaire` int(11) NOT NULL AUTO_INCREMENT,
  `user_pseudo` varchar(255) NOT NULL,
  `id_village` int(11) NOT NULL,
  `date_depot` datetime NOT NULL,
  `texte_commentaire` text NOT NULL,
  PRIMARY KEY (`id_commentaire`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;


Est-ce qu'il ne faut pas faire une requête SQL imbriquée ?

En attendant vos réponses, je continue mes recherches...
Cordialement

71 réponses

Avec ce code, il n'y a plus de WARNING mais maintenant, il me met :
Resource id #8
sur le premier article et
Resource id #9
sur le second

$query_selection_article_correspondant = mysql_query("SELECT * FROM articles, commentaires WHERE articles.titre_article=commentaires.titre_article") or die ('Erreur sur la requête SQL concernant la sélection de l\'article correspondant'.mysql_error()); // Envoie une requête à un serveur MySQL

if ($row=mysql_fetch_row($query_selection_article_correspondant)) {  
echo '
'.$query_selection_article_correspondant.'
';
} 


Cordialement
Messages postés
1540
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
1 août 2013
12
En fait je vais continuer à suivre la discussion en me poilant à chacune de tes tentatives insensées

PS : Tu connais l'expression RTFM ?
Avec ce code, j'ai réussi à afficher le commentaire qui est dans la base de données sous l'article mais le problème, maintenant, c'est qu'il s'affiche sous tout les articles et trois fois à chaque fois.

Voici le code PHP :

// Requête SQL pour déterminer l'identifiant de l'article correspondant - le faire à l'affichage
$query_selection_article_correspondant = mysql_query("SELECT * FROM articles, commentaires WHERE articles.titre_article=commentaires.titre_article") or die ('Erreur sur la requête SQL concernant la sélection de l\'article correspondant'.mysql_error()); // Envoie une requête à un serveur MySQL

while ($row = mysql_fetch_assoc($query_selection_article_correspondant)) {
   echo $row["user_pseudo"];
   echo $row["date_depot"];
   echo $row["texte_commentaire"];
}


Voici le résultat :
PseudoDateTitrePseudoDateTitrePseudoDateTitre

(trois fois)

En attendant vos réponses, je continue mes recherches...
Cordialement
Messages postés
1540
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
1 août 2013
12
T'as quoi dans ta base quand tu la requête depuis un client sûr (genre PHPMyAdmin) ?
Quand je teste cette requête SQL (
SELECT * FROM articles, commentaires WHERE articles.titre_article=commentaires.titre_article
sur PHPMyAdmin, ça me donne le résultat adéquat (deux occurrences pas en double).

Mais, je penses que le problème se situe lors de l'insertion des commentaires car je voudrais enregistrer le titre de l'article sur lequel le commentaire a été posté pour pouvoir, ensuite, le récupérer et surtout savoir avec quel article il correspond. Comment capter le titre de l'article sur lequel on effectue un commentaire ? C'est pour cela que j'ai fait la requête SQL avec la jointure.

Voici le code PHP qui s'occupe de l'insertion des commentaires dans la base de données :
// Insertion du commentaire dans la base de données
$req_insertion_texte_commentaire_article = "INSERT INTO commentaires(user_pseudo, nom_village, date_depot, texte_commentaire) VALUE ('$user_pseudo', '1', now(), '$texte_commentaire_article')";
$query_insertion_texte_commentaire_article = mysql_query($req_insertion_texte_commentaire_article) or die ('Erreur sur la requête SQL concernant l\'insertion des commentaires sur des articles'.mysql_error()); // Envoie une requête à un serveur MySQL
echo "Votre commentaire est posté.

";
}


Cordialement
Messages postés
1540
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
1 août 2013
12
Le plus sûr pour associer des données dans un SGBD relationnel (ce qu'est MySQL) c'est de créer une clé étrangère.
Dans ta table "commentaire" il faut rajouter un champ qui pointe vers la clé unique de ta table "article".
Tu peux voir ici comment déclarer une clé étrangère (FOREIGN KEY en anglais).
PHPMyAdmin te propose peut-être une interface simplifiée pour le faire (je connais pas bien, perso j'utilise Toad).
Salut

J'ai fait cette requête SQL :
ALTER TABLE  `sgbdd`.`commentaires` ADD UNIQUE  `FOREIGN KEY` (  `id_article` )


Depuis, quand je fais cette requête SQL
SELECT * FROM articles, commentaires WHERE articles.titre_article=commentaires.titre_article
, ça me fait :
-depuis PHPMyAdmin :
debug : #1054 - Unknown column 'commentaires.titre_article' in 'where clause'{"success":false,"error":"
#1054 - Unknown column 'commentaires.titre_article' in 'where clause'<\/div>"}

-depuis le site : quand je mets à la main l'id de l'article qui correspond, pour l'instant j'ai trois articles et ça met le commentaire sous les trois articles. Donc, à mon avis j'ai déconné en mettant la FOREIGN KEY, non ?

En attendant vos réponses, je continue mes recherches...
Cordialement
Pour information quand je vais voir les CREATE TABLE des deux tables, voici les requêtes :
-Commentaires :
CREATE TABLE IF NOT EXISTS `commentaires` (
  `id_commentaire` int(11) NOT NULL AUTO_INCREMENT,
  `user_pseudo` varchar(255) DEFAULT NULL,
  `nom_village` varchar(255) NOT NULL,
  `nom_categorie` varchar(255) NOT NULL,
  `date_depot` datetime NOT NULL,
  `texte_commentaire` text NOT NULL,
  `id_article` int(11) NOT NULL,
  UNIQUE KEY `PRIMARY KEY` (`id_commentaire`),
  UNIQUE KEY `FOREIGN KEY` (`id_article`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=48 ;


-Articles :
CREATE TABLE IF NOT EXISTS `articles` (
  `id_article` int(11) NOT NULL AUTO_INCREMENT,
  `nom_village` varchar(255) CHARACTER SET latin1 NOT NULL,
  `nom_categorie` varchar(255) CHARACTER SET latin1 NOT NULL,
  `date_depot` datetime NOT NULL,
  `titre_article` varchar(255) NOT NULL,
  `texte_article` text NOT NULL,
  `auteur_article` varchar(255) NOT NULL,
  PRIMARY KEY (`id_article`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=84 ;


Qu'est-ce que tu en penses ?

En attendant vos réponses, je continue mes recherches...
Cordialement
Au fait, j'ai oublié de te dire la chose la plus importante : maintenant sur le site, le commentaire ne s'affiche plus trois fois mais qu'une fois par article mais s'affiche toujours sur tout les articles (alors que je voudrais l'afficher sous l'article correspondant sur lequel l'utilisateur l'a posté, logique non ?!).
Je te mets le résultat :
AuteurDate formatée en PHP
Contenu du commentaire


Voici la boucle en PHP :
// Requête SQL pour déterminer l'identifiant de l'article correspondant - le faire à l'affichage
$query_selection_article_correspondant = mysql_query("SELECT * FROM articles, commentaires WHERE articles.id_article=commentaires.id_article") or die ('Erreur sur la requête SQL concernant la sélection de l\'article correspondant'.mysql_error()); // Envoie une requête à un serveur MySQL

while ($row = mysql_fetch_assoc($query_selection_article_correspondant)) {
   echo $row["user_pseudo"];
   echo dateLongue($row["date_depot"]);
   echo $row["texte_commentaire"];
}


A mon avis, il y a un bug sur la clé étrangère (FOREIGN KEY).

En attendant vos réponses, je continue mes recherches...
Cordialement
Messages postés
1540
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
1 août 2013
12
Plusieurs choses :
- commentaires.id_commentaire doit être une PRIMARY KEY, pas juste UNIQUE,
- commentaires.id_article doit être une FOREIGN KEY, certainement pas UNIQUE.
--> tu confonds "type de contrainte" et "nom de contrainte".

Pour le premier point (PRIMARY KEY) regarde comment tu as fais dans la table article sur le champ id_article : il faut faire pareil.
Pour le deuxième point (FOREIGN KEY) regarde le lien que je t'ai passé plus haut, tout y est expliqué, avec des exemples.

Enfin, lors de ta jointure dans ta requête il faut passer par id_article, et non pas par titre_article (qui d'ailleurs ne semble même pas exister dans le CREATE TABLE commentaires que tu fais suivre ensuite).
Désormais, quand je fais la requête SQL sur PHPMyAdmin, il n'y a plus d'erreurs mais sur le site, c'est toujours pareil.

Voici les CREATE TABLE des deux tables :

Articles :
CREATE TABLE IF NOT EXISTS `articles` (
  `id_article` int(11) NOT NULL AUTO_INCREMENT,
  `nom_village` varchar(255) CHARACTER SET latin1 NOT NULL,
  `nom_categorie` varchar(255) CHARACTER SET latin1 NOT NULL,
  `date_depot` datetime NOT NULL,
  `titre_article` varchar(255) NOT NULL,
  `texte_article` text NOT NULL,
  `auteur_article` varchar(255) NOT NULL,
  PRIMARY KEY (`id_article`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=84 ;


Commentaires :
CREATE TABLE IF NOT EXISTS `commentaires` (
  `id_commentaire` int(11) NOT NULL AUTO_INCREMENT,
  `user_pseudo` varchar(255) DEFAULT NULL,
  `nom_village` varchar(255) NOT NULL,
  `nom_categorie` varchar(255) NOT NULL,
  `date_depot` datetime NOT NULL,
  `texte_commentaire` text NOT NULL,
  `id_article` int(11) NOT NULL,
  PRIMARY KEY (`id_commentaire`),
  KEY `FOREIGN KEY` (`id_article`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=48 ;


Voici le code PHP dans lequel j'ai remplacé le titre par l'ID :
		
// Requête SQL pour déterminer l'identifiant de l'article correspondant - le faire à l'affichage
$query_selection_article_correspondant = mysql_query("SELECT * FROM articles, commentaires WHERE articles.id_article=commentaires.id_article") or die ('Erreur sur la requête SQL concernant la sélection de l\'article correspondant'.mysql_error()); // Envoie une requête à un serveur MySQL

while ($row = mysql_fetch_assoc($query_selection_article_correspondant)) {
   echo $row["user_pseudo"];
   echo dateLongue($row["date_depot"]);
   echo $row["texte_commentaire"];
}


Qu'est-ce que tu en penses ?

En attendant vos réponses, je continue mes recherches...
Cordialement
Messages postés
1540
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
1 août 2013
12
Je dis que tout est bon sauf la définition de la FOREIGN KEY.
As-tu regardé le lien que je t'ai passé ? J'ai des doutes.
Faut-il rajouter la FOREIGN KEY dans la table articles car elle dépend l'une de l'autre ?

En attendant vos réponses, je continue mes recherches...
Cordialement
J'ai fait ça :
ALTER TABLE commentaires 
ADD FOREIGN KEY (id_article)
REFERENCES articles(id_article);


Est-ce que c'est ça ? A mon avis non car rien n'a changé.

En attendant vos réponses, je continue mes recherches...
Cordialement
Messages postés
1540
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
1 août 2013
12
C'est la bonne syntaxe pour ajouter une clé étrangère sur ton champ commentaires.id_article, oui.
Si ce SQL est passé alors ça a changé quelque chose et ton script de création ne devrait plus ressembler à celui que tu me montres.

Et non il n'y a rien à faire sur la table articles.
Donc, ce que j'ai fait ce matin, tout est bon ?

Maintenant, il faut aller voir le code PHP qui s'occupe de l'insertion des commentaires. Je te mets le code PHP mais je sais qu'il y a un bug dans la requête SQL INSERT INTO :
// strip_tags = Supprime les balises HTML et PHP d'une chaîne
$texte_commentaire_article=$_POST["texte_commentaire_article"];
$titre_article = $donnees_messages['titre_article'];
// Enregistrement du pseudo de l'utilisateur (variable de session) pour pouvoir l'utiliser dans la requête INSERT INTO
$user_pseudo = $_SESSION["user_pseudo"];

//$titre_article = mysql_query("SELECT 'titre_article.articles' FROM articles, commentaires WHERE articles.titre_article=commentaires.titre_article") or die ('Erreur sur la requête SQL concernant l\'insertion des commentaires sur des articles'.mysql_error()); // Envoie une requête à un serveur MySQL

// Insertion du commentaire dans la base de données
$req_insertion_texte_commentaire_article = "INSERT INTO commentaires(user_pseudo, nom_village, date_depot, texte_commentaire) VALUE ('$user_pseudo', '1', now(), '$texte_commentaire_article')";
$query_insertion_texte_commentaire_article = mysql_query($req_insertion_texte_commentaire_article) or die ('Erreur sur la requête SQL concernant l\'insertion des commentaires sur des articles'.mysql_error()); // Envoie une requête à un serveur MySQL
echo "Votre commentaire est posté.

";
}


Voici le code PHP actualisé maintenant :
// strip_tags = Supprime les balises HTML et PHP d'une chaîne
$texte_commentaire_article=$_POST["texte_commentaire_article"];
// Enregistrement du pseudo de l'utilisateur (variable de session) pour pouvoir l'utiliser dans la requête INSERT INTO
$user_pseudo = $_SESSION["user_pseudo"];

$query_recherche_bon_article = "SELECT articles.id_article FROM articles, commentaires WHERE articles.id_article=commentaires.id_article";

// Insertion du commentaire dans la base de données

$req_insertion_texte_commentaire_article = "INSERT INTO commentaires(user_pseudo, nom_village, date_depot, texte_commentaire, id_article) VALUE ('$user_pseudo', '1', now(), '$texte_commentaire_article, '$query_recherche_bon_article')";
$query_insertion_texte_commentaire_article = mysql_query($req_insertion_texte_commentaire_article) or die ('Erreur sur la requête SQL concernant l\'insertion des commentaires sur des articles'.mysql_error()); // Envoie une requête à un serveur MySQL
echo "Votre commentaire est posté.

";
}


Voici l'erreur que ça me donne :
Erreur sur la requête SQL concernant l'insertion des commentaires sur des articlesYou have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT articles.id_article FROM articles, commentaires WHERE articles.id_article' at line 1


Maintenant, il faut réussir à capter l'article sur lequel le commentaire est posté...

En attendant vos réponses, je continue mes recherches...
Cordialement
Juste pour information, quand je vais sur PHPMyAdmin voir le contenu de la table commentaires, je vois que l'id_article est en bleu. Quand je clique dessus, il m'affiche le résultat de la requête SQL
SELECT * FROM  `articles` WHERE  `id_article` =83 LIMIT 0 , 30
alors qu'avant non donc ça ça montre qu'on a avancé !

En attendant vos réponses, je continue mes recherches...
Cordialement
Messages postés
1540
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
1 août 2013
12
La requête d'insertion que tu montes (dans la variable $req_insertion_texte_commentaire_article Sands)n'a pas de sens. Tu y incruste ta requête select ($query_recherche_bon_article) entre quote.

De plus cette sous-requête n'a rien à faire ici. Pour connaitre l'identifiant de l'article sur lequel tu commentes il faut s'y prendre autrement, d'une manière dépendante de ton interface (id_article dans le GET ou un input quelconque si tu affiches un article par page, id_article dans un input hidden ou en attribut de tes submits si plusieurs sur la même page). Tu ne trouveras pas cet identifiant par l'opération du saint esprit.
Pour récupérer l'identifiant de chaque article, j'ai fait :
$query_selection_article_correspondant = mysql_query("SELECT articles.id_article, commentaires.date_depot, commentaires.texte_commentaire,commentaires.user_pseudo FROM articles, commentaires WHERE articles.id_article=commentaires.id_article") or die ('Erreur sur la requête SQL concernant la sélection de l\'article correspondant'.mysql_error()); // Envoie une requête à un serveur MySQL

$query_selection_article_id_correspondant = mysql_query("SELECT articles.id_article, articles.titre_article FROM articles, commentaires") or die ('Erreur sur la requête SQL concernant la sélection de l\'article correspondant'.mysql_error()); // Envoie une requête à un serveur MySQL


while ($row mysql_fetch_assoc($query_selection_article_correspondant)&&$row2 mysql_fetch_assoc($query_selection_article_id_correspondant)) {
   echo $row["id_article"];
   echo $row["user_pseudo"];
   echo dateLongue($row["date_depot"]);
   echo $row["texte_commentaire"];
}


C'est n'importe quoi, je sais, mais je continue de chercher...

En attendant vos réponses, je continue mes recherches...
Cordialement
Messages postés
1540
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
1 août 2013
12
Attention ta 2ème requête n'a pas de clause where pour la jointure, tu vas te retrouver avec la multiplication des deux tables. Et je ne vois pas l'utilité de faire ces deux requêtes. Voilà un pseudo code pour t'orienter :

 - je récupère tous mes articles (MySQL)
 - pour chaque article trouvé :
   - j'affiche le titre, la date et le contenu de l'article
   - je récupère tous les commentaires liés à cet article (MySQL)
   - pour chaque commentaire :
     - j'affiche l'auteur, la date et le contenu du commentaire
   - je génère un formulaire d'envoi d'un commentaire, avec l'attribut value du submit égal à l'id_article.

Cet algo peut-être optimisé pour minimiser les allers/retours entre server PHP et server MySQL,
mais si t'arrives à mettre celui-ci en place ce sera déjà pas mal.