Partage
  • Partager sur Facebook
  • Partager sur Twitter

Requete imbriquee sur une seule table

Est-ce faisable ?

    6 janvier 2011 à 11:36:08

    Bonjour bonjour !

    Je souhaite faire un import de donnees de la table1 à une table2.
    Initialement, les donnees de la table se presente sous cette forme:

    champ1 champ2 champ3 champ4 champ5 champ6 champ7 champ8
    E 148 RCE 1 toto ErreurB1 texteErreurA1 01-01-2011
    E 148 RCE 2 toto texteErreurA2 01-01-2011
    E 148 RCE 3 toto texteErreurA3 01-01-2011
    E 148 RCE 4 toto texteErreurA4 01-01-2011
    E 162 RCE 1 toto ErreurV26 texteErreurK 01-01-2011
    E 219 RCE 1 toto ErreurF15 texteErreurM1 01-01-2011
    E 219 RCE 2 toto texteErreurM2 01-01-2011



    Dans les grandes lignes:
    je souhaite importer toutes les donnees en concatenant le champ 7pour chaque identifiant de champ2,
    le champ6 identifie le type de l'erreur, et n'etant declare qu'une fois, le champ4 etant l'incrementation des champ7 .
    Apres plusieurs tests de requete et de nombreux messages d'erreurs dans phpmyadmin, je me pose quelques questions:
    1/ est ce possible de faire une requete avec des SELECT imbriqués ou des JOIN sur une seule table ?
    2/ Dois faire cela en plusieurs etapes, soit en plusieurs requetes ?
    3/ Est il preferable de traiter un SELECT * FROM matable entierement en php et de concatener mes bouts de requetes ?

    Le resultat que je veux atteindre est celui ci:


    champ1 champ2 champ3 champ4 champ5 champ6 champ7 champ8
    E 148 RCE 1 toto ErreurB1 texteErreurA1.texteErreurA2.texteErreurA3.texteErreurA4 01-01-2011
    E 162 RCE 1 toto ErreurV26 texteErreurK1.texteErreurK2 01-01-2011
    E 219 RCE 1 toto ErreurF15 texteErreurM1.texteErreurM2 01-01-2011


    J'ai essayé des choses comme ceci, mais est-ce la bonne logique ?

    SELECT * FROM `temp_table` AS TT1
    JOIN `temp_table` AS TT2 
    ON TT1.champ2 =TT2.champ2
    WHERE 
    (SELECT DISTINCT champ2
    FROM `temp_table` AS TT3 
    ORDER BY champ4 ASC ) = TT1.champ3
    



    Merci d'avance pour votre coup de main !
    • Partager sur Facebook
    • Partager sur Twitter
      6 janvier 2011 à 11:46:58

      bonjour,
      oui tu peux travailler sur la même table. ça a même un nom : auto-jointure (qui peut être une auto-equi-jointure, une auto-theta-jointure, ...).
      Idem pour les requêtes imbriquées.
      L'obligatoire c'est de mettre des alias, ce que tu as fait.
      Il y a tout un tas d'exemples basiques et classiques : obtenir hiérarchique de untel, obtenir les subordonnés de untel, obtenir les collègues de untel, ... dans une table Salaries ...

      • Partager sur Facebook
      • Partager sur Twitter
        6 janvier 2011 à 11:56:24

        Pourquoi mettre un ORDER BY dans la sous-requête ?

        A priori tu auras besoin (je suppose que tu utilises MySQL) d'un GROUP_CONCAT (je t'invite à jeter un coup d'oeil dans la doc ;) http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html) pour obtenir le champ7 dans le deuxième tableau que tu donnes :)

        Pour le reste, il te manque certainement un GROUP BY contenant quasi toutes les colonnes (sauf a priori les champs 4, 6 et 7 :) )

        EDIT: Voici un exemple de requête qui résoud ton problème tel que tu l'as donné, il existe d'autres solutions, peut-être plus performantes, mais celle-ci exprime bien ce que tu demandes d'après moi :)

        SELECT
        	champ1,
        	champ2,
        	champ3,
        	MIN(champ4) AS champ4,
        	champ5,
        	MAX(champ6) AS champ6,
        	GROUP_CONCAT(champ7 ORDER BY champ4 SEPARATOR '.') AS champ7,
        	champ8
        FROM test
        GROUP BY champ1, champ2, champ3, champ5, champ8;
        
        • Partager sur Facebook
        • Partager sur Twitter
          7 janvier 2011 à 11:23:08

          Bonjour sicilien007 et Shepard !

          Merci pour vos prestes et précieuses indications !
          J'ai fait plein de tests, et ta solution Shepard est vraiment pas mal.
          Sauf que, et oui il fallait bien un "mais", je me suis aperçu que la fonction MAX() ne me permettait pas de récupérer les "doublons".
          En fait le champ6 peut être le même pour le même champ2, comme dans l'exemple ci-dessous .
          Pour être plus clair, le champ6 est un code d'erreur, le champ7 sur la même ligne est le libelle de l'erreur, et les champs "champ7"qui suivent en dessous et ayant sur la même ligne un champ6 vide, sont les commentaires des erreurs.

          Je peux donc avoir le même code erreur avec le même libellé plusieurs fois, pour un même champ2.
          La fonction Max() ne me retourne donc pas l'intégralité des datas si:
          -Il y a un "doublon" d'erreur,
          -Pour un même champ2 (148 par exemple), si j'ai une valeur ErreurV48 et une autre ErreurF87, il ne me sera retourné que la valeur Max, soit ErreurF87.

          Voyez le schmilblik ??! :o


          Je crois que je vais passer par le php et une seconde requete, l'histoire des champs concatenes et des doublons ne me paraissent pas etre gerables en SQL.



          Ce à quoi je me heurte !
          champ1 champ2 champ3 champ4 champ5 champ6 champ7 champ8
          E 148 RCE 1 toto ErreurB1 titreErreurA1 01-01-2011
          E 148 RCE 1 toto texteErreurA2 01-01-2011
          E 148 RCE 1 toto texteErreurA3 01-01-2011
          E 148 RCE 1 toto texteErreurA4 01-01-2011
          E 148 RCE 1 toto ErreurB1 titreErreurA1 +1 01-01-2011
          E 148 RCE 1 toto texteErreurA2 01-01-2011
          E 148 RCE 1 toto texteErreurA3 01-01-2011



          Merci si vous avez des pistes ! je continue mes tests !
          Tchô.
          • Partager sur Facebook
          • Partager sur Twitter
            7 janvier 2011 à 12:21:03

            Tu aimerais obtenir quoi comme résultat ? A priori rien ne permet de dire si la dernière ligne appartient à l'une ou l'autre erreur :s Je dois avouer avoir du mal à te suivre :s
            • Partager sur Facebook
            • Partager sur Twitter
              7 janvier 2011 à 13:45:55

              Salut Shepard !

              Merci pour ta disponibilité et ton aide. :D C'est très urbain !!!
              Mon but est de passer des infos d'une table temporaire à une table finale, mieux gaulée, et je pensais le faire en une requete SELECT pour déjà "formater" mes données à insérer.

              En gros pour chaque champ2 j'ai un nombre d'erreurs, renseignées par le code erreur, son libellé et des lignes de commentaires. Pour chaque champ2 je peux avoir plusieurs erreurs, et plusieurs fois la même erreur :colere2: ( pour lesquelles seul le contenu des commentaires changera, ainsi que le libellé, en général incrémenté cf +1).
              Je cherche a concaténer tous les libellés et commentaires dans une seule case, voire deux ( case "libellé" et case " commentaires concaténés") .
              Le champ4 est l'incrémentation du nombre de lignes renseignées pour le champ2, ici par exemple pour la valeur 148 au champ2 on aura 9 lignes, 3 erreurs donc deux du même type, et des commentaires



              Visuellement:
              J'ai ca: :-°
              champ1 champ2 champ3 champ4 champ5 champ6 champ7 champ8
              E 148 RCE 1 toto Code erreur B1 Libelle erreurB1 01-01-2011
              E 148 RCE 2 toto commentaire ligne 1 01-01-2011
              E 148 RCE 3 toto commentaire ligne 2 01-01-2011
              E 148 RCE 4 toto commentaire ligne 3 01-01-2011
              E 148 RCE 5 toto Code erreurB1 Libelle erreurB1 +1 01-01-2011
              E 148 RCE 6 toto commentaire ligne 1 01-01-2011
              E 148 RCE 7 toto commentaire ligne 2 01-01-2011
              E 148 RCE 8 toto Code erreurA63 Libelle erreurA63 01-01-2011
              E 148 RCE 9 toto commentaire ligne 1 01-01-2011
              E 162 RCE 1 toto Code erreurV26 Libelle erreurV26 01-01-2011
              E 162 RCE 2 toto commentaire ligne 1 01-01-2011
              E 219 RCE 1 toto Code erreurF15 Libelle erreurF15 01-01-2011
              E 219 RCE 2 toto commentaire ligne 1 01-01-2011



              Je souhaiterai obtenir ca : o_O
              champ1 champ2 champ3 champ4 champ5 champ6 champ7 champ8
              E 148 RCE 1 toto Code erreurB1 Libelle erreurB1.commentaire ligne 1.commentaire ligne 2.commentaire ligne 3.--Libelle erreurB1 +1.commentaire ligne 1.commentaire ligne 2. 01-01-2011
              E 148 RCE 1 toto Code erreurA63 Libelle erreurA63.commentaire ligne 1 01-01-2011
              E 162 RCE 1 toto Code erreurV26 Libelle erreur26.commentaire ligne 1 01-01-2011
              E 219 RCE 1 toto Code erreurF15 Libelle erreurF15.commentaire ligne 1 01-01-2011


              Je me dirige plus vers une gestion avec deux requêtes et un peu de php.
              Mais si tu as un bon tuyau, ma foi ....
              Tchô !
              • Partager sur Facebook
              • Partager sur Twitter
                7 janvier 2011 à 14:30:59

                Pour le champ4 de la réponse attendue, la deuxième ligne ne doit-elle pas plutôt contenir 8 ?

                Edit: J'arrive au résultat attendu (avec la note ci-dessus) à l'aide d'une vue (ce serait un peu trop le bordel sinon :D)

                Dis moi si ça te convient :)

                (vue)
                create view test_dep as
                select
                	t1.champ1,
                	t1.champ2,
                	t1.champ3,
                	t1.champ4,
                	t1.champ5,
                	t1.champ6,
                	if(t1.champ6 is null, max(t2.champ4), t1.champ4) as dep,
                	t1.champ7,
                	t1.champ8
                from test t1
                	left join test t2 on t1.champ1 = t2.champ1
                		and t1.champ2 = t2.champ2
                		and t1.champ3 = t2.champ3
                		and t2.champ4 < t1.champ4
                		and t2.champ6 is not null
                group by t1.champ1, t1.champ2, t1.champ3, t1.champ4, t1.champ5, t1.champ6, t1.champ7, t1.champ8
                


                (requête)
                select
                	champ1, champ2, champ3, min(champ4), champ5, champ6,
                	group_concat(champ7 order by champ4 separator '--') as champ7,
                	champ8
                from (
                	select
                		champ1, champ2, champ3, champ5, champ8,
                		min(champ4) as champ4, max(champ6) as champ6,
                		group_concat(champ7 order by champ4 separator '.') as champ7
                	from test_dep
                	group by champ1, champ2, champ3, champ5, dep, champ8
                ) t
                group by champ1, champ2, champ3, champ5, champ6, champ8;
                
                • Partager sur Facebook
                • Partager sur Twitter
                  7 janvier 2011 à 14:52:47

                  Merci Shepard !

                  Quelle promptitude !
                  je decortique ce que tu m'as proposé, je me renseigne sur les views que je connais trop peu, je lis ton tuto sql, et je fais mes tests. Une fois tout ça fini, je te dirai si tu mérites une bière... ou deux ! :p
                  Faut vraiment que je me remette au sql plus en profondeur !

                  Merci encore ! a bientôt !
                  :)
                  • Partager sur Facebook
                  • Partager sur Twitter
                    11 janvier 2011 à 16:09:00

                    Salut Shepard !
                    j'ai bien potassé mon sql et j'ai même lu ton tuto sql.
                    Je suis plus à l'aise avec les vues et j'ai bien compris ce que tu m'as proposé.
                    Cependant je me heurte à autre chose : une simple requete CREATE VIEW ne passe pas sur mon phpmyadmin, alors que sur un validateur sql ca passe à l'aise. Je me tourne donc vers la version de phpmyadmin que j'ai, soit mov'amp 0.5, avec une version du client MySQL: 5.0.37, ce qui correspond ( cf la doc mysql: "Les vues (y compris les vues modifiables) sont implémentées en version 5 de MySQL. Les vues sont disponibles dans les versions binaires depuis la version 5.0.1 et plus récent."). Par contre dans les types de requête que je trouve sur les statuts serveur il n'y a pas VIEW ou CREATE VIEW comme requete possible !

                    Tu vois ce que ça peut vouloir dire ?
                    Si pret du but, en ayant compris ce que tu m'as donné !!! rhaaa!! carrement rageant !
                    Type de requête
                    • Partager sur Facebook
                    • Partager sur Twitter
                      11 janvier 2011 à 21:30:44

                      À mon avis il faut mettre à jour ta version de PHPMyAdmin, mov'amp semble être un projet mort depuis plusieurs années ...

                      Si c'est pour le fait de pouvoir l'installer sur une clé usb que tu l'utilises, EasyPHP permet maintenant l'installation sur une clé également :) Sinon WampServer est pas mal (c'est ce que j'utilisais quand je travaillais sous Windows).

                      PHPMyAdmin gère les vues, j'en suis quasi persuadé :p

                      Sinon avec PHPMyAdmin, même s'il ne semble pas gérer les vues, tu devrais pouvoir exécuter la requête SQL directement non ? Et la vue devrait logiquement apparaître dans la colonne de gauche :)

                      N'hésite pas à redemander si ces pistes ne fonctionnent pas :p
                      • Partager sur Facebook
                      • Partager sur Twitter
                        14 janvier 2011 à 9:27:34

                        Salut Shepard !

                        bon, mon probleme venait bien de mov'amp, et je suis passé sous easyphp, meme si j'eus prefere wamp !
                        bref les views fonctionnent. Par contre avec tous les champs de ma table ca mouline trop. Je passe donc au php.
                        Ceci dit merci pour ton aide en sql, j'ai (re)decouvert plein de trucs dont je ne me servais plus, et j'ai aussi vu que tu as un tuto sql à ton actif !!! la classe ! :D

                        Pour le php, en reprenant le meme tableau de donnees, et toujours pour concatener mes champs de libelles, en ne gardant que les infos sans doublons, je pense me servir des numeros de lignes des commentaires ( le champ4 du tableau).
                        Une question, comment definir en php mes "intervalles" pour faire mes requetes.
                        En francais ca ferai: Selectionne moi le champ2, le champ4 et le champ6 et champ7 quand le champ7 est renseigné.-> boucle sur les resultats puis definition des intervalles pour selectionner les champs a concatener: Selectionne moi les champ6 vides pour le meme champ2 compris entre intervalle1 et intervalle2. La ou je bloque "techniquement" :euh: c'est comment definir et declarer ces intervalles, un modulo ? des if/else ?
                        Est ce que je suis dans la bonne reflexion pour traiter mon probleme ? o_O

                        Merci pour votre dispo !
                        • Partager sur Facebook
                        • Partager sur Twitter

                        Requete imbriquee sur une seule 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