Partage
  • Partager sur Facebook
  • Partager sur Twitter

Différence de résultats entre deux requêtes

Non prise en compte de l'ensemble des liens

Sujet résolu
    13 janvier 2020 à 23:11:03

    Bonjour,

    J'ai relu le cours sur les jointures des bases SQL et je n'arrive pas à comprendre pourquoi deux requêtes apparemment identiques ne donnent pas le même résultat. Peut-être que je me trompe de chapitres...

    Voilà le schéma des tables.

    MCD
    Une table "DC_Episodes" et une table "DC_Thèmes toutes deux reliées par "DC_Episodes_Themes". Un épisode peut contenir un ou plusieurs thèmes ou pas du tout ; Un thème peut être présent dans un ou plusieurs épisodes ou pas du tout (elle sert aussi pour d'autres tables).

    Je veux connaître le numéro, le titre anglais et les thèmes de l'épisode 345 :

    SELECT
        E.Id AS Id,
        E.Numero AS Numero,
        E.Titre_ang AS Titre_anglais,
        GROUP_CONCAT(DISTINCT T.Nom SEPARATOR ', ' ) AS Themes
    FROM
        DC_Episodes E
            LEFT JOIN DC_Episodes_Themes ET
                ON E.Id = ET.Episode_Id
            LEFT JOIN DC_Themes T
                ON ET.Thid = T.Id
    WHERE
        E.Numero = '345'
        GROUP BY E.id;

      
    Cela affiche :



    J'ai bien deux thèmes qui s'affichent, dans la colonne thème, séparés par une virgule.

    Si je recherche, maintenant, les épisodes associés à l'identifiant de thème 7 :

    SELECT
        E.Id AS Id,
        E.Numero AS Numero,
        E.Titre_ang AS Titre_anglais,
        GROUP_CONCAT(DISTINCT T.Nom SEPARATOR ', ' ) AS Themes
    FROM
        DC_Episodes E
            LEFT JOIN DC_Episodes_Themes ET
                ON E.Id = ET.Episode_Id
            LEFT JOIN DC_Themes T
                ON ET.Thid = T.Id
    WHERE
        T.Id = '7'
        GROUP BY E.id;

    Il affiche :



    L'épisode 345, pour reprendre l'exemple précédent, n'a plus qu'un thème alors qu'il est bien associé à deux.

    J'ai fait les essais suivants :
    – Retirer le "DISTINCT" dans le GROUP_CONCAT ;
    – Essayer de faire deux jointures de DC_Themes en donnant un alias différent ;
    – Partir d'une recherche "SELECT FROM DC_Themes" ;
    – Enlever le "GROUP BY" final...

    Rien n'y fait. Dès lors que j'effectue une recherche par thème, il ne prend pas en compte les autres thèmes possibles du même épisode.

    La requête avait pourtant l'air simple de prime abord. Je ne comprends pas pourquoi, juste avec un changement de condition dans le WHERE, cela ne fonctionne plus. Quelqu'un a-t-il une idée, s'il vous plaît ?

    -
    Edité par KerberosK 13 janvier 2020 à 23:11:48

    • Partager sur Facebook
    • Partager sur Twitter
      14 janvier 2020 à 15:01:02

      KerberosK a écrit:

      L'épisode 345, pour reprendre l'exemple précédent, n'a plus qu'un thème alors qu'il est bien associé à deux.

      KerberosK a écrit:

      Dès lors que j'effectue une recherche par thème, il ne prend pas en compte les autres thèmes possibles du même épisode

      Si tu filtres seulement seulement sur un thème ... les autres thèmes ne peuvent apparaître ...

      Maintenant, si tu devais exprimer en français le résultat attendu, que serait-ce ? "La liste des épisodes liés à un thème donnés avec tous leurs thèmes liés" ?

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        14 janvier 2020 à 19:37:55

        Bonsoir,

        Merci pour la réponse.

        Effectivement, ce que je souhaite, c'est obtenir "la liste des épisodes ayant un thème donné avec tous les thèmes qui leur sont liés". Pardon, si je m'exprime mal.

        J'ai réussi à obtenir le résultat attendu. J'ignore s'il est "propre" :

        SELECT
            E.Id AS Id,
            E.Numero AS Numero,
            E.Titre_ang AS Titre_anglais,
            GROUP_CONCAT(DISTINCT T.Nom SEPARATOR ', ' ) AS Themes
        FROM
            DC_Episodes E
                LEFT JOIN DC_Episodes_Themes ET
                    ON E.Id = ET.Episode_Id
                LEFT JOIN DC_Themes T
                    ON ET.Thid = T.Id
                LEFT JOIN DC_Episodes_Themes ET2
                    ON E.Id = ET2.Episode_Id
                LEFT JOIN DC_Themes T2
                    ON ET2.Thid = T2.Id           
        WHERE
            T2.Id = '7'
            GROUP BY E.id;



        J'avais essayé, dans un premier temps, de joindre deux fois la table des thèmes, sans succès. Cela fonctionne en joignant deux fois et la table des thèmes et celle qui la relie à celle des épisodes.

        J'ai la requête que je voulais mais je ne comprends pas sa logique.

        Benzouye a écrit:

        Si tu filtres seulement seulement sur un thème ... les autres thèmes ne peuvent apparaître ...


        Dans ma requête, je demande "Tous les épisodes ayant pour thème...", cela ne veut pas dire qu'ils n'en ont qu'un.

        Désolé, j'ai un peu de mal à saisir.

        -
        Edité par KerberosK 14 janvier 2020 à 19:39:42

        • Partager sur Facebook
        • Partager sur Twitter
          15 janvier 2020 à 9:32:04

          KerberosK a écrit:

          Dans ma requête, je demande "Tous les épisodes ayant pour thème...", cela ne veut pas dire qu'ils n'en ont qu'un.

          La clause WHERE theme = 7 ne sélectionnera que les themes 7, pas les autres.

          Mais bravo pour ta deuxième requête. D'abord tu sélectionnes tous les épisodes liés au thème 7 (avec l'alias T2), ensuite tu joins quand même à tous les autres thèmes (avec l'alias T).

          Maintenant, il te faut connaître un fonctionnement autour des jointures externes (ici LEFT JOIN) : Si tu places une condition dans la clause WHERE sur une table en jointure externe, alors cela revient à faire une jointure interne.

          Ta deuxième requête équivaut donc à :

          SELECT
          	E.Id AS Id,
          	E.Numero AS Numero,
          	E.Titre_ang AS Titre_anglais,
          	GROUP_CONCAT(DISTINCT T.Nom SEPARATOR ', ' ) AS Themes
          FROM
          	DC_Episodes E
          		INNER JOIN DC_Episodes_Themes ET2
          			ON E.Id = ET2.Episode_Id
          		INNER JOIN DC_Themes T2
          			ON ET2.Thid = T2.Id
          		LEFT JOIN DC_Episodes_Themes ET
          			ON E.Id = ET.Episode_Id
          		LEFT JOIN DC_Themes T
          			ON ET.Thid = T.Id	  
          WHERE T2.Id = '7'
          GROUP BY E.id;
          • Partager sur Facebook
          • Partager sur Twitter
          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
            15 janvier 2020 à 17:29:52

            D'accord, Je comprends mieux le lien WHERE/Jointure Interne.

            Merci pour l'explication.

            • Partager sur Facebook
            • Partager sur Twitter

            Différence de résultats entre deux requêtes

            × 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