Partage
  • Partager sur Facebook
  • Partager sur Twitter

Jointure assez spéciale

Sujet résolu
    17 septembre 2010 à 20:21:34

    Hellow

    J'aimerais faire une jointure un peu complexe. En fait, j'ai une table qui contient des schémas de construction, une qui contient les constructions faites à partir de ces schémas, liée à une autre table qui contient les bases où ont été faites ces constructions.
    J'aimerais récupérer la construction de la base 1 faite à partir du schema 1. Le souci, c'est que s'il n'y a pas eu de construction, la requête ne se fait pas. Un exemple :

    SELECT * FROM `schema` s
    LEFT OUTER JOIN building bu ON bu.schema_id = s.schema_id
    RIGHT OUTER JOIN base b ON b.base_id = bu.base_id
    WHERE b.base_id = 1 AND s.schema_id = 1
    
    -- Ne renvoie rien
    


    Quelqu'un saurait-il m'aider ? Ca fait plusieurs heures que je tourne en rond...

    Edit : ce que j'aimerais récupérer même s'il n'y a aucune construction, c'est au moins le schéma et la base.
    • Partager sur Facebook
    • Partager sur Twitter
      17 septembre 2010 à 22:09:11

      C'est pas une très bonne idée d'appeler ta table "schema". Essaie d'éviter les mots clés réservés au SGBDR, ça alourdit les requêtes pour pas grand-chose.

      Sinon, comment veux-tu récupérer le schéma ET la base s'il n'y a aucune construction, en sachant que c'est avec une ligne dans la table construction que tu fais le lien entre le schéma et la base ? C'est impossible, il faudrait une autre foreign key quelque part.
      • Partager sur Facebook
      • Partager sur Twitter
        17 septembre 2010 à 22:47:38

        Bah, j'me disais que comme je renseigne dans le where l'id de la base et du schema que je veux, il y aurait un moyen pour qu'il me retourne les données du schema, de la base et du bâtiment s'il existe.
        En français, ça donnerait :

        Trouve moi la base X, le schéma Y et, s'il existe, le bâtiment Z qui correspond aux deux.
        En toute logique, des jointures externes devraient fonctionner, vu qu'elles renvoient le résultat même s'il n'y a pas correspondance...

        Merci pour l'astuce du nom, au fait, mais je n'ai rien trouvé de mieux à ce jour... Y'a bien "plan" en français, mais faire du franco-anglais, c'est pas mon truc :p
        • Partager sur Facebook
        • Partager sur Twitter
          17 septembre 2010 à 23:25:33

          Si tu sais toujours schema_id et base_id, tu peux faire un truc du genre :
          SELECT S.schema_id, U.building_id, B.base_id 
          FROM schemas S 
          LEFT OUTER JOIN building U
              ON S.schema_id = U.schema_id 
          INNER JOIN base B 
              ON B.base_id = 1 
          WHERE S.schema_id = 1;
          


          Ça retourne U.building_id correctement s'il existe, sinon NULL, mais rien ne te confirme que base_id existe. Et tu dois toujours connaître schema_id et base_id, sinon ça fonctionne pas. Personnellement, je crois que tu as un problème de conception quelque part.
          • Partager sur Facebook
          • Partager sur Twitter
            18 septembre 2010 à 0:04:32

            \o/ Merci, ça marche parfaitement !

            Ce n'est pas vraiment une erreur de conception, enfin, je pense pas. J'ai une table qui liste les schémas possibles, avec des champs comme le nom, la description, quelques images,... J'ai une table qui contient les bases dans lesquelles les constructions sont possibles. Les constructions faites dans ces bases sont dans une table de jointure, en quelque sorte, pour une relation [n,n] (n bâtiments peuvent être construits dans n bases, mais 1 seul bâtiment de même schéma sera possible par base).

            Sinon, pas d'inquiétude, je connaîtrai obligatoirement schema_id et base_id, vu qu'on ne peut pas lancer de construction sans connaître le plan ni l'endroit où on veut le construire ;)
            • Partager sur Facebook
            • Partager sur Twitter
              18 septembre 2010 à 0:11:03

              À mon avis, il te manque une table qui lie la table schemas à la table base. Passer par une bidouille comme je l'ai fait ne me semble pas une solution viable, alors que s'il existait une telle table, il n'y aurait eu qu'à faire la jointure et faire la condition dans le WHERE plutôt que dans la jointure.

              Mais bon, je suis pas expert en conception de bases de données, je crois simplement que ce serait plus logique.

              Edit: Présentement, c'est impossible de faire une jointure entre la table schema et base alors que s'il existait une table pour faire le lien, ce serait ultra simple. La requête que tu veux faire présentement serait beaucoup plus simple :

              SELECT L.schema_id, L.base_id, U.building_id
              FROM schema_base L
              LEFT OUTER JOIN building U
                  ON L.base_id = U.base_id
              WHERE L.schema_id = 1 AND L.base_id = 1;
              


              Ça me semble être beaucoup plus flexible.
              • Partager sur Facebook
              • Partager sur Twitter
                18 septembre 2010 à 0:30:43

                Sauf qu'il n'existe absolument aucune relation entre un schéma et une base, sauf bien sûr la construction en question. Essaye d'associer le plan d'un musée à une ville, genre Paris. Y'a aucune relation qui existe entre les deux, et pourtant...
                • Partager sur Facebook
                • Partager sur Twitter
                  18 septembre 2010 à 0:36:24

                  Et pourtant, tu en cherches une. C'est ça, le problème. Il y a à quelque part une erreur parce que c'est exactement ce que tu essaies de faire : trouver qu'est-ce qui relie le schéma à la base. Je ne vois pas ce qu'il y a de mal à associer le plan d'un musée à son lieu de construction, ça me semble pas du tout irrationnel.

                  Enfin, c'est toi qui sais.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    18 septembre 2010 à 1:33:16

                    Sauf quand le musée peut être construit dans plusieurs villes différentes. Tu ne peux pas associer un plan de bâtiment à une ville spécifique. Mon exemple était ptet mal choisi, vois plutôt la fabrication de vis. Une vis, t'as un plan, et des milliards d'exemplaires. Là, c'pareil. Pourtant, le projet où ta vis est utilisée n'est en rien reliée au plan.
                    Tu vois où je veux en venir ? Il n'y a aucune liaison plausible, sauf l'exemplaire en question, qui peut exister ou non.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      18 septembre 2010 à 2:16:39

                      J'imagine que le plan est le même pour toutes les villes, si c'est le même schéma. La relation existe déjà, tu ne l'as simplement pas encore créée. Regarde ta question : tu vois bien que tu as une relation, quelque part, entre le schéma et la base si tu es capable, à partir de ces deux données, de trouver la construction. Et regarde ma requête : on crée la relation avec une constante parce qu'elle n'existe pas ailleurs.

                      Je ne continuerai pas d'argumenter, tu sais plus que moi ce dont tu as besoin pour ton projet. Je te donne mon avis, si tu crois que tu ne peux pas faire une autre table en sachant que cela résoudrait bien des problèmes, c'est que tu as une bonne raison.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        18 septembre 2010 à 15:59:49

                        Eh non, finalement, la requête ne marche pas... Je suis obligé de rajouter une clause au where : AND U.base_id = 1 , sinon ça me renvoie tous les bâtiments de toutes les bases avec le schéma 1, avec juste les infos de la base 1...
                        Je trouve ça bizarre quand même, que le LEFT + RIGHT ne fonctionne pas.

                        Edit: et avec cette nouvelle clause, quand il n'y a aucune construction, ça ne me renvoie rien... Revenu au point de départ :-/

                        Edit2: J'ai finalement réglé le problème en allant sur le chan irc de mysql. On m'a trouvé la solution de la jointure croisée :

                        SELECT *
                        FROM `schema` s CROSS JOIN base b
                        LEFT JOIN building bu
                          ON bu.schema_id = s.schema_id AND b.base_id = bu.base_id
                        WHERE `s`.`schema_id` = 1 AND `ba`.`base_id` = 1;
                        


                        Merci de ton aide Fayden ;)
                        • Partager sur Facebook
                        • Partager sur Twitter

                        Jointure assez spéciale

                        × 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