Partage
  • Partager sur Facebook
  • Partager sur Twitter

PHP, comment faire les jointures avec trois table?

je n'arrive pas à faire la jointure avec trois tables!

    5 mars 2023 à 14:02:17

    Salut.

    Je suis en plein apprentissage de création des sites dynamiques!

    je souhaite faire une jointure avec trois tables sql.

    les tables sont:

    1: User (contient les informations des membre)

    id_membre	pseudo	sexe	date_inscription
    1	         dyce	  m	2023-03-01
    2	         loulou   m	2023-03-01
    3	         kheci    f	2023-03-02
    4	         louche	  f	2023-03-04
    

    2: Amis (table membre ayant des amis)

    id_ami	id_demande_invite	id_recois.invite	Accepte_invite
    1	       1	               4	               1
    2	       1	               2	               0
    3	       4	               2	               1
    

    3: vitrine (table ayant les bublications des membres)

    id.vitrine	id_ecrit_vitrine	id_proprio_vitrine	poste.vitrine	 Date_vitrine
    1	               1  1       Salut la famille	 2023-03-04
    2	                1 4	       Trop de soleil	 2023-03-04
    3	                2	                2	       Bonjour           2023-03-04
    4	                2	                4	       Mais tu n’es  	 2023-03-04
                                                                   toujourspas là 
                                                                   Louche?



    je voudrais afficher les publications de la session active ainsi que celle de ses amis.

    Le code php que j'ai utilisé pour le faire, mais rien ! 

    :pirate: le problème est que je n'arrive pas à prendre les publications des amis qui ont (accepte_invitation = 1).

    e
    
    <?php// Récupération des 30 dernieres publications
    
    
    //jointure avec trois table
    				$reponse = $bdd->prepare('SELECT 
    					v.id_vitrine AS id_v, 
    					v.id_ecrit_vitrine AS post_v,
    					v.id_proprio_vitrine AS proprio_v, 
    					DATE_FORMAT(v.date_vitrine, \'%d/%m/%Y\') AS date_poste_contenu_membre, 
    								
    					u.id_membre,
    					u.pseudo,
    					u.sexe;
    					DATE_FORMAT(v.u.date_inscription, \'%d/%m/%Y\') AS date_membre_inscrit,
    								
    					a.id_demande_invite AS demande_a,
    					a.id_recois_invite AS recois_a,
    					a.accepte_invite AS invitation_accepter
    					
                                      FROM user u
    										
    				JOIN Amis A
    				       ON u.id_membre= a.id_demande_invite AND a.id_recois_invite
    				       INNER JOIN vitrine_contenu s
    				       ON u.id_membre = s.Id.ecrit.vitrine AND s.id_membre_ecrit_vitrine
    										
    				WHERE v.id_ecrit_vitrine =:session AND v.id_proprio_vitrine=:session
    				      OR v.id_ecrit_vitrine =:session AND v.id_proprio_vitrine!=:session
    				      OR v.id_ecrit_vitrine !=:session AND v.id_proprio_vitrine=:session
    										
    				      OR v.id_ecrit_vitrine = a.id_demande_invite AND v.id_proprio_vitrine =a.id_recois_invite AND a.accepte_invite = 1
    										
    		                      OR v.id_ecrit_vitrine = a.id_demande_invite AND v.id_proprio_vitrine !=a.id_recois_invite  AND a.accepte_invite = 1
    										
    				      OR v.id_ecrit_vitrine !=a.id_demande_invite AND v.id_proprio_vitrine=a.id_recois_invite  AND a.accepte_invite = 1
    										
    						ORDER BY date_vitrine
    						DESC LIMIT 0,30');
    						$reponse->execute(array(
    					        "session"=>$_SESSION['id']  
    							));
    											
    			// la jointure avec les trois tables ne fonctionne pas!
    											?>

    Cordialement. 

    • Partager sur Facebook
    • Partager sur Twitter
      6 mars 2023 à 10:12:42

      Salut

      Est-ce que tu peux être plus clair sur ce qui te fait dire que « la jointure avec les trois tables ne fonctionne pas » ? As-tu bien activé l'affichage des erreurs de PHP ET de ton outil de connexion à la base de données (PDO ou mysqli) ?

      Fais bien attention aux AND et OR : suivant ce que tu cherches à faire, il te faudra peut-être des parenthèses supplémentaires.

      Ligne 16, tu as mis v.u.date_inscription, cette notation suit la forme base.table.colonne, je ne pense pas que ce soit ce que tu souhaites faire, c'est peut-être un des sinon le souci.

      • Partager sur Facebook
      • Partager sur Twitter
        6 mars 2023 à 22:48:41

        As-tu bien activé l'affichage des erreurs de PHP ET de ton outil de connexion à la base de données (PDO ou mysqli) ? Oui, ils sont bien actéver!


        Je sais bien faire les jointures avec deux tables 

        exemple ce code qui fonctionne bien:

        <?php// Récupération des 30 dernieres publications
        
        
        //jointure avec deux tables
        								$reponse = $bdd->prepare('SELECT 
        								v.id_vitrine AS id_v, 
        								v.id_ecrit_vitrine AS post_v,
        								v.id_proprio_vitrine AS proprio_v, 
        								DATE_FORMAT(v.date_vitrine, \'%d/%m/%Y\') AS date_poste_contenu_membre, 
        								
        								u.id_membre,
        								u.pseudo,
        								u.sexe;
        								DATE_FORMAT(v.u.date_inscription, \'%d/%m/%Y\') AS date_membre_inscrit,
        								
        								FROM User u
        										
        								INNER JOIN Vitrine s
        										ON u.id_membre = v.id_ecrit_vitrine AND v.id_proprio_vitrine
        										
        										WHERE v.id_ecrit_vitrine =:session AND v.id_proprio_vitrine=:session
        										OR v.id_ecrit_vitrine =:session AND v.id_proprio_vitrine!=:session
        										OR v.id_ecrit_vitrine !=:session AND v.id_proprio_vitrine=:session
        										
        										ORDER BY date_vitrine
        										DESC LIMIT 0,30');
        										$reponse->execute(array(
        											 "session"=>$_SESSION['id']  
        											));
        											
        				// la jointure avec les deux tables fonctionne très bien!
        											?>
        • Partager sur Facebook
        • Partager sur Twitter
          7 mars 2023 à 9:31:55

          Bien, bien, et les autres points que j’avais mentionnés, notamment l'autre question ?

          -
          Edité par Ymox 7 mars 2023 à 9:32:38

          • Partager sur Facebook
          • Partager sur Twitter
            7 mars 2023 à 11:53:35

            Je viens juste de vérifié le code et tu avais bien raison!!

            Regade ça!

            <?php 
            								
            								// Récupération des 30 dernieres publications
            								$reponse = $bdd->prepare('SELECT v.id_vitrine AS id_vitrine, v.contenu_vitrine AS contenue_membre, DATE_FORMAT(v.date_enter_contenu, \'%d/%m/%Y\') AS date_poste_contenu_membre, date_edit_contenu, v.id_membre_post_vitrine AS membre_ecrit_vitrine, v.id_membre_ecrit_vitrine AS proprio_vitrine_ecrit, v.jaime AS jaime_vitrine, v.nom_commentaire AS commentaire_vitrine, v.image_vitrine AS image_de_poster_dans_la_vitrine, u.pseudo AS expediteur_message, u.sex_membre AS sex_expediteur, u.avatar AS avatar_expediteur
            								
            								(a.id_expediteur_invitation + a.id_destinateur_invitation -:session) AS amis_id, a.active AS demande_accepter
            								
            										FROM user u
            										INNER JOIN vitrine_contenu v
            										ON u.id = v.id_membre_post_vitrine AND v.id_membre_ecrit_vitrine AND u.id = a.id_expediteur_invitation AND u.id = a.id_destinateur_invitation
            										
            										
            										
            										WHERE v.id_membre_post_vitrine = a.id_expediteur_invitation AND v.id_membre_ecrit_vitrine = a.id_destinateur_invitation AND  AND a.active = :OK_accept  
            										
            										ORDER BY date_edit_contenu
            										DESC LIMIT 0,30');
            										$reponse->execute(array(
            											 "session"=>$_SESSION['id'],
            											 "OK_accept"=>'1' 
            											));
            											
            											
            								// Affichage de chaque message (toutes les données sont protégées par htmlspecialchars)
            								while ($d = $reponse->fetch())
            								{
            									?>



            • Partager sur Facebook
            • Partager sur Twitter
              7 mars 2023 à 14:29:42

              Je m'en veux un peu de m'auto-citer, mais apparemment ça ne passe pas, alors…

              Ymox a écrit:

              Est-ce que tu peux être plus clair sur ce qui te fait dire que « la jointure avec les trois tables ne fonctionne pas » ?

              Donc dire pourquoi ça ne fonctionne pas, ce que tu observes et que tu ne penses pas être correct.

              Parce que le message ci-dessus n'est pas vraiment plus clair sur le fait que le problème est résolu ou non… surtout que ce n'est pas le code pour la même chose qu'au début du sujet.

              -
              Edité par Ymox 7 mars 2023 à 14:32:45

              • Partager sur Facebook
              • Partager sur Twitter
                8 mars 2023 à 15:25:19

                Excuse moi et merci pour ton précieux temps .

                Je suis en développement de mon site web dynamique et j'apprends en même temps le php!

                Le premier code était juste un exercice et le second est celui que utilise.

                Je n'est pas de code d'erreur non plus, mais c'est juste que je n'avais jamais réalisé une JOINTURE avec trois tables. Et en suivent bien tes premiers conseils de vérification, j'ai vite compris que c'étais les connaissance même qui me manquais.

                Je souhaite afficher les flux des activités des membre ainsi que leur amis comme sur facebook (exp: Aubin aime une publication. Jean a écrit sur le mur de Paul. Vous avez commenté une photo)

                Mon problème est dans WHERE:

                - J'ai bien récupéré les informations  des trois tables avec le SELECT:

                $reponse = $bdd->prepare('SELECT v.id_vitrine AS id_vitrine, v.contenu_vitrine AS contenue_membre, DATE_FORMAT(v.date_enter_contenu, \'%d/%m/%Y\') AS date_poste_contenu_membre, date_edit_contenu, v.id_membre_post_vitrine AS membre_ecrit_vitrine, v.id_membre_ecrit_vitrine AS proprio_vitrine_ecrit, v.jaime AS jaime_vitrine, v.nom_commentaire AS commentaire_vitrine, v.image_vitrine AS image_de_poster_dans_la_vitrine,
                			u.id AS id_membre, u.pseudo AS expediteur_message, u.sex_membre AS sex_expediteur, u.avatar AS avatar_expediteur,
                			(a.id_expediteur_invitation + a.id_destinateur_invitation -:session AS amis_id), a.active AS demande_accepter

                - Les JOINTUREs aussi fonctionne bien!

                FROM user u
                	INNER JOIN vitrine_contenu v
                	    ON u.id = v.id_membre_post_vitrine AND v.id_membre_ecrit_vitrine 
                										
                	JOIN amis a
                	ON u.id = a.id_expediteur_invitation AND a.id_destinateur_invitation

                * Le souci est dans la Close WHERE.

                1) Si je veux récupéré juste les publications que la logué a publié sur elle même (Ma requête est):

                WHERE v.id_membre_post_vitrine =:session AND id_membre_ecrit_vitrine = :session

                2) Si je souhaite juste afficher les publications qui ont été faite sur moi par d'autre (Ma requête est):

                WHERE v.id_membre_post_vitrine =:session AND id_membre_ecrit_vitrine != :session
                     OR v.id_membre_post_vitrine !=:session AND id_membre_ecrit_vitrine = :session

                3) cette requête affiche les publications du membre Logué ainsi que ses propre publications sauf les amis à qui le membre Logué a fait la demande bien qu'ayant accepter.   

                WHERE  (a.id_destinateur_invitation OR a.id_expediteur_invitation) AND a.active = :OK_accept

                " Je souhaite pouvoir afficher les publications des amis du membre Logué sur eux, sur d'autre personne par eux et ainsi que celle du membre Logué lui même!

                Merci Beaucoup

                • Partager sur Facebook
                • Partager sur Twitter
                  8 mars 2023 à 22:42:45

                  OK, donc le souci n'est pas que tu as une erreur et que ça ne fonctionne pas, mais que tu ne sais pas comment faire ce que tu veux. Je comprends vite quand on m'explique longtemps.

                  Par contre, je vais signaler ce sujet pour le faire déplacer dans le forum des bases de données. Je me débrouille en SQL, mais je peux aussi être totalement à côté de la plaque, et là-bas il y a des personnes largement plus compétentes.

                  Dans un premier temps, posons la requête de base. Tu as besoin des publications, donc je conseille de "partir" de la table des publications.

                  SELECT
                  			* -- je te laisse le soin de spécifier les champs dont tu as besoin
                  	FROM
                  			vitrine
                  

                  Il nous faut les informations de l'auteur, donc on va ajouter une jointure vers la table des utilisateurs.

                  SELECT
                  			*
                  	FROM
                  				vitrine v
                  		INNER JOIN
                  				user u
                  			ON
                  					v.id_proprio_vitrine = u.id
                  

                  Il va aussi nous falloir les notions d'amitié, donc on ajoute la jointure vers la table des invitations.

                  Petite subtilité cependant : même si ce sont les amis de l'utilisateur, on aimerait les publications des amis, donc on ne va pas joindre entre user et amis, mais entre vitrine et amis, en utilisant id_proprio_vitrine. Et c'est là que la notion d'amitié va entrer en jeu.

                  Techniquement, il te faut donc les publications où :

                  1. soit id_proprio_vitrine vaut celui de l'utilisateur authentifié, pour les publications faites par l'utilisateur lui-même ;
                    1. soit id_proprio_vitrine égale id_expediteur_invitation, là où id_destinateur_invitation vaut celui de l'utilisateur authentifié – pour les publications où l'utilisateur authentifié a été invité et a accepté ;
                    2. soit id_proprio_vitrine égale id_destinateur_invitation, là où id_expediteur_invitation vaut celui de l'utilisateur authentifié – pour les publications où l'utilisateur a invité

                    et accepte_invite vaut true – et l'invitation, faite par l'utilisateur authentifié ou un autre a été acceptée.

                  Je vais y faire une "jointure à gauche" pour qu'on ait les résultats aussi quand l'utilisateur n'a pas encore accepté d'invitation ou que ses invitations n'ont pas été invitées acceptées, ou encore qu'il n'y a aucune invitation qui le concerne. D'autre part, la jointure sera un peu faible du fait que l'ID qu'on doit y utiliser peut se trouver dans l'une ou l'autre colonne.

                  SELECT
                  			* -- attention à bien spécifier les champs
                  	FROM
                  				vitrine v
                  		INNER JOIN
                  				user u
                  			ON
                  					v.id_proprio_vitrine = u.id
                  		LEFT JOIN
                  				amis a
                  			ON
                  					-- point 2.1
                  					(	v.id_proprio_vitrine = a.id_expediteur_invitation
                  					-- point 2.2
                  					OR	v.id_proprio_vitrine = a.id_destinateur_invitation)
                  				-- fin du point 2
                  				AND	Accepte_invite = true
                  

                  Et finalement, il faut qu'on dise quel utilisateur est concerné, ce qui se fait simplement avec une clause WHERE.

                  L'ID de l'utilisateur authentifié est :

                  1. soit dans id_proprio_vitrine - l'utilisateur est directement l'auteur
                    1. soit dans id_expediteur_invitation - l'auteur est un ami que l’utilisateur a invité
                    2. soit dans id_destinateur_invitation - l'auteur est un ami qui a invité l'utilisateur
                  SELECT
                  			* -- attention à bien spécifier les champs
                  	FROM
                  				vitrine v
                  		INNER JOIN
                  				user u
                  			ON
                  					v.id_proprio_vitrine = u.id
                  		LEFT JOIN
                  				amis a
                  			ON
                  
                  					(	v.id_proprio_vitrine = a.id_expediteur_invitation
                  					OR	v.id_proprio_vitrine = a.id_destinateur_invitation)
                  				AND	Accepte_invite = true
                  	WHERE
                  		-- utilisateur authentifié directement propriétaire
                  			v.id_proprio_vitrine = :session
                  		-- ami que l'utilisateur a invité
                  		OR	a.id_expediteur_invitation = :session
                  		-- ami qui a invité l'utilisateur
                  		OR	a.id_destinateur_invitation = :session
                  

                  -
                  Edité par Ymox 13 mars 2023 à 17:37:24

                  • Partager sur Facebook
                  • Partager sur Twitter
                    8 mars 2023 à 22:49:06

                    Bonjour,

                    Déplacement vers un forum plus approprié

                    Le sujet est déplacé de la section PHP vers la section Base de données

                    • Partager sur Facebook
                    • Partager sur Twitter
                      13 mars 2023 à 13:18:50

                      BONJOUR ET GRAND MERCI :D A TOI Ymox

                      Tu a trouvé solution exacte à mes jointures:

                      Voici le code:

                      FROM vitrine_contenu v
                      		INNER JOIN user u
                      		ON u.id = v.id_membre_post_vitrine AND v.id_membre_ecrit_vitrine 
                      										
                      		LEFT JOIN
                      			amis a
                      		ON v.id_membre_ecrit_vitrine = a.id_expediteur_invitation + a.id_destinateur_invitation -:session 
                      		OR v.id_membre_post_vitrine = a.id_expediteur_invitation + a.id_destinateur_invitation -:session
                      										
                      		WHERE (a.id_expediteur_invitation = :session OR a.id_destinateur_invitation = :session) AND a.active = :OK_accept
                      										
                      		OR v.id_membre_post_vitrine =:session AND id_membre_ecrit_vitrine = :session
                      		OR v.id_membre_post_vitrine !=:session AND id_membre_ecrit_vitrine = :session
                      		OR v.id_membre_post_vitrine =:session AND id_membre_ecrit_vitrine != :session



                      Merci 

                      -
                      Edité par dyc@89 13 mars 2023 à 13:20:41

                      • Partager sur Facebook
                      • Partager sur Twitter
                        13 mars 2023 à 17:14:55

                        Bonjour,

                        Sujet résolu

                        Tu peux passer le sujet à "résolu" (bouton en haut à droite du sujet) et cliquer sur les pouces levés des messages qui t'ont aidé⋅e ;)
                        • Partager sur Facebook
                        • Partager sur Twitter
                          15 mars 2023 à 14:12:39

                          Hello,

                          je sais que le sujet est en résolu, mais je vois pas comment une jointure de ce genre peut fonctionner.

                          FROM vitrine_contenu v
                                  INNER JOIN user u
                                  ON u.id = v.id_membre_post_vitrine AND v.id_membre_ecrit_vitrine


                          C'est moi qui ai oublié les bases du SQL ? ou est-ce que ça ne peut pas fonctionner ?

                          • Partager sur Facebook
                          • Partager sur Twitter

                          PHP, comment faire les jointures avec trois table?

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                          • Editeur
                          • Markdown