Partage
  • Partager sur Facebook
  • Partager sur Twitter

WHERE et JOIN

Sujet résolu
    18 novembre 2010 à 16:31:45

    Bonjour,

    J'ai une requête dans laquelle j'utilise l'ancienne syntaxe des jointures (avec WHERE) et je souhaite la réécrire grâce à la nouvelle méthode (JOIN) mais je n'y arrive visiblement pas car les résultats des deux requêtes sont très différents.

    Requête avec WHERE:
    SELECT M.nom_matiere, C.coefficient, P.nom_prof, P.sexe
    FROM matiere M, coefficient C, prof P, classe CL, enseigner E
    WHERE CL.id_classe = ?
    AND C.id_classe = CL.id_classe
    AND C.id_matiere = M.id_matiere
    AND E.id_classe = CL.id_classe
    AND E.id_matiere = M.id_matiere
    AND E.id_prof = P.id_prof
    


    Requête avec JOIN:
    SELECT M.nom_matiere, C.coefficient, P.nom_prof, P.sexe
    FROM matiere M
    INNER JOIN enseigner E
    	ON E.id_matiere = M.id_matiere
    INNER JOIN prof P
    	ON P.id_prof = E.id_prof
    INNER JOIN classe CL
    	CL.id_classe = E.id_classe
    INNER JOIN coefficient C
    	ON C.id_matiere = M.id_matiere
    INNER JOIN coefficient CO
    	ON CO.id_classe = CL.id_classe
    WHERE CL.id_classe = ?
    


    Et voici ma base de données:
    BDD Bulletins

    Merci par avance pour votre aide. :)
    • Partager sur Facebook
    • Partager sur Twitter
      19 novembre 2010 à 10:08:48

      il faut mettre des parenthése, sinon, ta requête vas associer tous les INNER JOIN à ta table matière

      http://www.trucsweb.com/asp/trucs.asp?no=104&type=7 : regarde l'exemple #3

      par contre au niveau de ton MCD, c'est très très brouillon, je suis sûr que tu peux faire mieux que ça, surtout au niveau de classe, spéciliste...

      voilà
      • Partager sur Facebook
      • Partager sur Twitter
        19 novembre 2010 à 17:50:41

        Citation : icewind

        il faut mettre des parenthése, sinon, ta requête vas associer tous les INNER JOIN à ta table matière

        http://www.trucsweb.com/asp/trucs.asp?no=104&type=7 : regarde l'exemple #3



        Non, pas du tout. Les parenthèses sont tout à fait facultatives, la jointure (interne) étant une opération commutative et associative. Un exemple :

        vsavard_db=> CREATE TABLE j1 (j1_id integer, j1_nom varchar);
        CREATE TABLE
        Temps : 8,524 ms
        vsavard_db=> CREATE TABLE j2 (j2_id integer, j2_nom varchar);
        CREATE TABLE
        Temps : 7,769 ms
        vsavard_db=> CREATE TABLE jj (j1_id integer, j2_id integer);
        CREATE TABLE
        Temps : 3,282 ms
        vsavard_db=> INSERT INTO j1 (j1_id, j1_nom) SELECT n, 'Nom ' || n FROM generate_series (1, 10) n;
        INSERT 0 10
        Temps : 10,568 ms
        vsavard_db=> INSERT INTO j2 (j2_id, j2_nom) SELECT n, 'Nom ' || n FROM generate_series (1, 10) n;
        INSERT 0 10
        Temps : 1,613 ms
        vsavard_db=> INSERT INTO jj (j1_id, j2_id) VALUES (1, 4), (2, 2), (3, 7), (1, 3), (6, 3), (8, 9), (10, 3), (7, 3);
        INSERT 0 8
        Temps : 1,298 ms
        vsavard_db=> SELECT *
        vsavard_db-> FROM j1
        vsavard_db-> INNER JOIN jj ON j1.j1_id = jj.j1_id
        vsavard_db-> INNER JOIN j2 ON j2.j2_id = jj.j2_id;
         j1_id | j1_nom | j1_id | j2_id | j2_id | j2_nom 
        -------+--------+-------+-------+-------+--------
             2 | Nom 2  |     2 |     2 |     2 | Nom 2
             1 | Nom 1  |     1 |     3 |     3 | Nom 3
            10 | Nom 10 |    10 |     3 |     3 | Nom 3
             6 | Nom 6  |     6 |     3 |     3 | Nom 3
             7 | Nom 7  |     7 |     3 |     3 | Nom 3
             1 | Nom 1  |     1 |     4 |     4 | Nom 4
             3 | Nom 3  |     3 |     7 |     7 | Nom 7
             8 | Nom 8  |     8 |     9 |     9 | Nom 9
        (8 lignes)
        
        Temps : 1,410 ms
        vsavard_db=> SELECT *
        vsavard_db-> FROM jj
        vsavard_db-> INNER JOIN j2 ON jj.j2_id = j2.j2_id
        vsavard_db-> INNER JOIN j1 ON jj.j1_id = j1.j1_id;
         j1_id | j2_id | j2_id | j2_nom | j1_id | j1_nom 
        -------+-------+-------+--------+-------+--------
             2 |     2 |     2 | Nom 2  |     2 | Nom 2
             1 |     3 |     3 | Nom 3  |     1 | Nom 1
            10 |     3 |     3 | Nom 3  |    10 | Nom 10
             6 |     3 |     3 | Nom 3  |     6 | Nom 6
             7 |     3 |     3 | Nom 3  |     7 | Nom 7
             1 |     4 |     4 | Nom 4  |     1 | Nom 1
             3 |     7 |     7 | Nom 7  |     3 | Nom 3
             8 |     9 |     9 | Nom 9  |     8 | Nom 8


        Sinon, dans la première requête, tu ne joins qu'une seule fois la table coefficient tandis que dans la deuxième, tu la joins deux fois. Le problème doit venir de là.
        • Partager sur Facebook
        • Partager sur Twitter
          25 novembre 2010 à 16:36:24

          Dans la premiere version je joins aussi la table coefficient 2 fois...:

          AND C.id_classe = CL.id_classe
          AND C.id_matiere = M.id_matiere
          


          Donc retour au point de départ...

          Merci quand même pour votre aide. Quelqu'un a-t-il une autre idée?
          • Partager sur Facebook
          • Partager sur Twitter
            25 novembre 2010 à 23:10:04

            > Dans la premiere version je joins aussi la table coefficient
            > 2 fois...

            Non, elle n'y est qu'une seule fois, regarde dans la liste des tables (FROM), pas dans le where.

            Il suffit de mettre toutes les tables en JOIN et de mettre les conditions que tu mettais dans le WHERE à la bonne place (dans le bon JOIN quoi).

            Pour que ce soit plus lisible (ça ne change rien pour la BDD), je les ai aussi mises dans l'ordre logique de la requête, et j'ai retourné les conditions pour que tu aies JOIN X ON (X.colonne = ...) ce qui est plus facile à lire.

            SELECT M.nom_matiere, C.coefficient, P.nom_prof, P.sexe
            FROM classe CL 
            JOIN coefficient C ON (C.id_classe = CL.id_classe)
            JOIN matiere M     ON (M.id_matiere = C.id_matiere)
            JOIN enseigner E   ON (E.id_classe = CL.id_classe AND E.id_matiere = M.id_matiere)
            JOIN prof P        ON (P.id_prof = E.id_prof)
            WHERE CL.id_classe = ?
            


            Mais il y a plus simple :

            SELECT M.nom_matiere, C.coefficient, P.nom_prof, P.sexe
            FROM classe CL 
            JOIN coefficient C USING (id_classe)
            JOIN matiere M     USING (id_matiere)
            JOIN enseigner E   USING (id_classe,id_matiere)
            JOIN prof P        USING (id_prof)
            WHERE CL.id_classe = ?
            
            • Partager sur Facebook
            • Partager sur Twitter

            WHERE et JOIN

            × 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