Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Mariadb 10.4][PHP] Requete sur plusieurs tables

Sujet résolu
    4 mai 2021 à 9:51:49

    Bonjour,

    Je suis en train de développer un outil pour mon travail et je dois à présent effectuer une requête sql pour récupérer mon arborescence.

    Je m'explique j'ai dans ma base de données plusieurs tables:

    Une table

    -projet qui contient le nom et les données globales de plusieurs projet.

    -AL qui represente un lien entre projet et niveau

    -niveau qui représente mon arborescence (un niveau peut avoir un ou plusieurs enfants)

    -article qui correspond est contenu dans un niveau

    projet:

    niveau:

    al:

    Pour l'instant j'ai fait cette requète:

    SELECT * FROM article 
                INNER JOIN 
                niveau ON article.article_id = niveau.article_id
                INNER JOIN 
                arborescence_logistique ON arborescence_logistique.niveau_id IN
    (WITH RECURSIVE tree (niveau, id) 
        AS 
        (SELECT niveau_id, parent_id 
         FROM niveau N  
         UNION ALL 
         SELECT niveau_id, parent_id 
         FROM niveau V 
         INNER JOIN 
         tree t 
         ON t.id = V.niveau_id) 
        SELECT niveau 
        FROM tree 
        WHERE id IS NULL )
    INNER JOIN
                 projet
                 ON arborescence_logistique.projet_id = projet.projet_id
                 WHERE  projet.nom = :projet;

    Le soucis est que cette requète me renvoie même la ligne avec l'id 24 alors qu'elle n'est affecté à aucun projet?

    Ah et :projet = Mini projet test

    Je viens de remarquer un autre soucis aussi j'aimerai recevoir comme résultat de requète un tableau ordonné en fonction de mon arborescence.

    Donc le niveau mère tout en haut suivi du fils1 et de ses fils puis le fils 2 suivi de ses fils et etc or avec cette requète le résultat est trié par niveau_id.

    Exemple du tableau:

    Voilà j'attends avec impatience vos réponses

    -
    Edité par Ma-nie 4 mai 2021 à 10:26:43

    • Partager sur Facebook
    • Partager sur Twitter
      5 mai 2021 à 9:56:19

      Bonjour, je me permets de remettre un message pour relancer la demande. Car je suis toujours bloqué et ne trouve pas la solution

      Merci pour votre aide.

      • Partager sur Facebook
      • Partager sur Twitter
        5 mai 2021 à 13:16:23

        Bonjour,

        C'est le IN qui ne va pas ... Tous les AL sont sélectionnés ici, donc tous les projets ...

        WITH RECURSIVE tree ( niveau, id ) AS (
        	
        	SELECT
        		niveau_id,
        		parent_id
        	FROM niveau N
        	
        	UNION ALL
        	
        	SELECT niveau_id, parent_id
        	FROM
        		niveau V
        			INNER JOIN tree t
        				ON t.id = V.niveau_id
        
        )
        
        SELECT
        	...
        FROM
        	tree T
        		INNER JOIN niveau N
        			ON T.niveau = N.niveau_id
        		INNER JOIN arborescence_logistique AL
        			ON N.niveau_id = AL.niveau_id
        		INNER JOIN projet P
        			ON AL.projet_id = P.projet_id
        		INNER JOIN article A
        			ON N.article_id = A.article_id
        WHERE P.nom = '...'
        ORDER BY T.parent_id, T.niveau
        • Partager sur Facebook
        • Partager sur Twitter
        Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
          5 mai 2021 à 14:29:42

          Bonjour Benzouye,

          suite à votre message j'ai essayé en adaptant la requête.

          J'ai donc essayé avec cette requète:

          WITH RECURSIVE tree ( niveau, id ) AS (
               
                          SELECT
                              niveau_id,
                              parent_id
                          FROM niveau N
                           
                          UNION ALL
                           
                          SELECT niveau_id, parent_id
                          FROM
                              niveau V
                                  INNER JOIN tree T
                                      ON t.id = V.niveau_id
                       
                      )
                      SELECT * FROM tree T
                       INNER JOIN niveau N
                                  ON T.niveau = N.niveau_id
                              INNER JOIN arborescence_logistique AL
                                  ON N.niveau_id = AL.niveau_id
                              INNER JOIN projet P
                                  ON AL.projet_id = P.projet_id
                              INNER JOIN article A
                                  ON N.article_id = A.article_id
                      WHERE P.nom = "..."

          Le problème est que cela me renvoie toujours la même ligne:


          Ce nouveau problème vient de la requète par WITH n'est-ce pas ?

          Merci pour votre retour:)

          • Partager sur Facebook
          • Partager sur Twitter
            5 mai 2021 à 15:40:32

            Si tu n'as pas remplacé les "..." cette requête devrait d'ailleurs ne rien retourner :p

            Mais le WITH doit merder oui ...

            Peux-tu juste regarder ce que donne :

            WITH RECURSIVE tree ( niveau, id ) AS (
                 
                SELECT
                    niveau_id,
                    parent_id
                FROM niveau N
                WHERE parent_id IS NULL
                
                UNION ALL
                 
                SELECT niveau_id, parent_id
                FROM
                    niveau V
                        INNER JOIN tree t
                            ON t.id = V.niveau_id
             
            )
            SELECT * FROM tree;

            J'ai rajouté le parent_id IS NULL ...

            -
            Edité par Benzouye 5 mai 2021 à 15:43:13

            • Partager sur Facebook
            • Partager sur Twitter
            Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
              5 mai 2021 à 15:54:41

              J'avais bien remplacé les "..." par ma valeur à test :) Je les ai juste remis pour la publication sur le forum!


              Sinon ta requète me renvois ceci:

              Il me renvois donc bien les deux niveau "racine"  (celui que je veux récupéré ainsi que ses éléments fils et celui que je ne veux justement pas) le soucis c'est qu'on ne récupère pas ces fameux éléments fils justement.

              Merci de prendre de ton temps pour moi :D

              • Partager sur Facebook
              • Partager sur Twitter
                5 mai 2021 à 16:36:29

                Mais oui !!! C'est la jointure de ta récursive qui n'était pas bonne ...

                Si tu fais t.id = V.niveau_id rien ne matchera jamais ...

                C'est :

                WITH RECURSIVE tree ( niveau, id ) AS (
                      
                    SELECT
                        niveau_id,
                        parent_id
                    FROM niveau N
                    WHERE parent_id IS NULL
                     
                    UNION ALL
                      
                    SELECT niveau_id, parent_id
                    FROM
                        niveau V
                            INNER JOIN tree t
                                ON t.niveau = V.parent_id
                  
                )
                SELECT * FROM tree
                ORDER BY id, niveau;

                Du coup :

                WITH RECURSIVE tree ( niveau, id ) AS (
                	
                	-- Les niveaux racine
                	SELECT
                		niveau_id,
                		parent_id
                	FROM niveau
                	WHERE parent_id IS NULL
                	
                	UNION ALL
                	
                	-- Les niveaux découlants
                	SELECT niveau_id, parent_id
                	FROM
                		niveau V
                			INNER JOIN tree t
                				ON t.niveau = V.parent_id
                
                )
                
                SELECT
                	A.designation_article,
                	P.Nom_Projet,
                	N.niveau_id,
                	N.parent_id
                FROM
                	tree T
                		INNER JOIN niveau N
                			ON T.niveau = N.niveau_id
                		INNER JOIN arborescence_logistique AL
                			ON N.niveau_id = AL.niveau_id
                		INNER JOIN projet P
                			ON AL.projet_id = P.projet_id
                		INNER JOIN article A
                			ON N.article_id = A.article_id
                WHERE P.nom = 'Mini projet test'
                ORDER BY T.id, T.niveau

                -
                Edité par Benzouye 5 mai 2021 à 16:36:56

                • Partager sur Facebook
                • Partager sur Twitter
                Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                  6 mai 2021 à 8:16:25

                  Alors effectivement cela me ressort le niveau "racine" qui correspond bien à mon projet 'Mini projet test' mais je n'ai donc plus cette arborescence que j'aimerai récupérer...

                  Est-ce que je devrait faire une requète récursive imbriquée avec le résultat de celle la pour récupérer toute mon arborescence ou y a t-il une solution plus propre et facile ?

                  EDIT: en fait ce qui me pose problème c'est cette clause WHERE! Y a t-il une solution simple pour récupérer tout les fils du niveau retourné par cette requête.

                  Merci a toi :)

                  -
                  Edité par Ma-nie 6 mai 2021 à 8:57:33

                  • Partager sur Facebook
                  • Partager sur Twitter
                    6 mai 2021 à 9:28:41

                    WITH RECURSIVE tree ( niveau, id ) AS (
                           
                        SELECT
                            niveau_id,
                            parent_id
                        FROM niveau N
                        WHERE parent_id IS NULL
                          
                        UNION ALL
                           
                        SELECT niveau_id, parent_id
                        FROM
                            niveau V
                                INNER JOIN tree t
                                    ON t.niveau = V.parent_id
                       
                    )
                    SELECT * FROM tree
                    ORDER BY id, niveau;

                    Cette requête devrait ressortir l'arborescence complète présente en base, et bien ordonnée.

                    Maintenant, il faut que ta récursive parte du niveau affecté à ton projet (dans la première partie de l'UNION) :

                    WITH RECURSIVE tree ( niveau, id ) AS (
                    	 
                    	-- Les niveaux racine
                    	SELECT
                    		N.niveau_id,
                    		N.parent_id
                    	FROM
                    		niveau N
                    			INNER JOIN arborescence_logistique AL
                    				ON N.niveau_id = AL.niveau_id
                    			INNER JOIN projet P
                    				ON AL.projet_id = P.projet_id
                    	WHERE P.nom = 'Mini projet test'
                    	 
                    	UNION ALL
                    	 
                    	-- Les niveaux découlants
                    	SELECT niveau_id, parent_id
                    	FROM
                    		niveau V
                    			INNER JOIN tree t
                    				ON t.niveau = V.parent_id
                     
                    )
                    SELECT * FROM tree
                    ORDER BY id, niveau;

                    Cette requête devrait ressortir l'arborescence complète partant du niveau affecté au projet donné, et bien ordonnée.

                    Si c'est OK, tu peux faire la requête entière :

                    WITH RECURSIVE tree ( niveau, id ) AS (
                    	 
                    	-- Les niveaux racine
                    	SELECT
                    		N.niveau_id,
                    		N.parent_id
                    	FROM
                    		niveau N
                    			INNER JOIN arborescence_logistique AL
                    				ON N.niveau_id = AL.niveau_id
                    			INNER JOIN projet P
                    				ON AL.projet_id = P.projet_id
                    	WHERE P.nom = 'Mini projet test'
                    	 
                    	UNION ALL
                    	 
                    	-- Les niveaux découlants
                    	SELECT niveau_id, parent_id
                    	FROM
                    		niveau V
                    			INNER JOIN tree t
                    				ON t.niveau = V.parent_id
                     
                    )
                     
                    SELECT
                    	A.designation_article,
                    	P.Nom_Projet,
                    	N.niveau_id,
                    	N.parent_id
                    FROM
                    	tree T
                    		INNER JOIN niveau N
                    			ON T.niveau = N.niveau_id
                    		INNER JOIN arborescence_logistique AL
                    			ON N.niveau_id = AL.niveau_id
                    		INNER JOIN projet P
                    			ON AL.projet_id = P.projet_id
                    		INNER JOIN article A
                    			ON N.article_id = A.article_id
                    WHERE P.nom = 'Mini projet test'
                    ORDER BY T.id, T.niveau

                    -
                    Edité par Benzouye 6 mai 2021 à 9:30:04

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                      6 mai 2021 à 10:05:56

                      Alors là merci mais tellement merci à toi!!

                      Mais comme je suis jamais satisfait j'ai un nouveau problème, le tri, là on a trié en fonction de l'id mais ce n'est pas tout à fait ce que je veux le but est vraiment de trier en fonction de l'arborescence.

                      Exemple:

                      La racine puis son premier fils puis ses fils et etc puis le deuxieme fils de la racine et ses fils et etc...

                      J'ai donc essayé en enlevant le ORDER BY T.id, T.niveau car les id ne correspondent pas à l'ordre de mon arbo car un élément peut être ajouté dans le futur.

                      Le soucis c'est qu'en enlevant ce tri mon arbo est trié de la façon suivante :

                      racine puis ses fils puis les fils de ses fils et etc...

                      Un petit screen de mon résultat:

                      On voit donc bien (en fonction du code lcn que ce n'est pas bien trié)! Ah! Et j'oubliais mais le code LCN a été construit pour les test de cette façon pour un besoin de lisibilité mais dans le futur il pourra être totalement diférent donc je ne peux pas trier dessus! :(

                      EDIT:

                      J'ai essayé de faire un tri en ajoutant un pathstr mais hélas je n'ai pas de résultat concluant. Mais il ne doit pas manquer grand chose...

                      WITH RECURSIVE tree ( niveau, id, level, pathstr) 
                                  AS 
                                  ( -- Les niveaux racine 
                                  SELECT N.niveau_id, N.parent_id,0,CAST('' AS VARCHAR(255)) 
                                  FROM niveau N 
                                  INNER JOIN arborescence_logistique AL 
                                  ON N.niveau_id = AL.niveau_id 
                                  INNER JOIN projet P 
                                  ON AL.projet_id = P.projet_id 
                                  WHERE P.nom = "Mini projet test"
                                  UNION ALL 
                                  -- Les niveaux découlants 
                                  SELECT niveau_id, parent_id,t.level + 1, t.pathstr + A.designation_article
                                  FROM niveau V 
                                      INNER JOIN article A
                                      ON V.article_id = A.article_id
                                  INNER JOIN tree t 
                                  ON t.niveau = V.parent_id ) 
                                  SELECT * 
                                  FROM tree T
                                  INNER JOIN niveau N
                                      ON T.niveau = N.niveau_id
                      			INNER JOIN article A
                                  ON N.article_id = A.article_id
                                  ORDER BY pathstr

                      -
                      Edité par Ma-nie 6 mai 2021 à 11:40:35

                      • Partager sur Facebook
                      • Partager sur Twitter
                        6 mai 2021 à 12:17:04

                        La colonne "Code LCN" c'est quel champ en base ? C'est sur cette colonne qu'il faut trier ...

                        WITH RECURSIVE tree ( niveau, id ) AS (
                              
                            -- Les niveaux racine
                            SELECT
                                N.niveau_id,
                                N.parent_id
                            FROM
                                niveau N
                                    INNER JOIN arborescence_logistique AL
                                        ON N.niveau_id = AL.niveau_id
                                    INNER JOIN projet P
                                        ON AL.projet_id = P.projet_id
                            WHERE P.nom = 'Mini projet test'
                              
                            UNION ALL
                              
                            -- Les niveaux découlants
                            SELECT niveau_id, parent_id
                            FROM
                                niveau V
                                    INNER JOIN tree t
                                        ON t.niveau = V.parent_id
                          
                        )
                          
                        SELECT *
                        FROM
                            tree T
                                INNER JOIN niveau N
                                    ON T.niveau = N.niveau_id
                                INNER JOIN arborescence_logistique AL
                                    ON N.niveau_id = AL.niveau_id
                                INNER JOIN projet P
                                    ON AL.projet_id = P.projet_id
                                INNER JOIN article A
                                    ON N.article_id = A.article_id
                        WHERE P.nom = 'Mini projet test'
                        ORDER BY N.code_lcn
                        • Partager sur Facebook
                        • Partager sur Twitter
                        Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                          6 mai 2021 à 13:24:35

                          Parfait merci à toi j'y avais pensé mais ça n'avait pas encore été validé par l'équipe mais c'est tout bon à présent.

                          Bonne journée à toi:)

                          • Partager sur Facebook
                          • Partager sur Twitter

                          [Mariadb 10.4][PHP] Requete sur plusieurs tables

                          × 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