Partage
  • Partager sur Facebook
  • Partager sur Twitter

[MySQL] Requête avec tables multiples et jointures

Sujet résolu
    20 avril 2010 à 3:22:16

    Bonsoir à tous,

    Alors j'ai un petit problème : je n'arrive pas à construire une requête comptant des éléments distincts. Voici la construction de mes tables :

    Table "themes"


    • id_theme (int, AI)
    • nom_theme (varchar)

    Table "jonction_themes_parutions"


    • id_jonction (int, IA)
    • id_theme (int)
    • id_parution (int)

    Table "jonction_themes_articles"


    • id_jonction (int, IA)
    • id_theme (int)
    • id_article (int)

    Tables "parutions" et "articles"


    Elles ne sont pas vraiment importantes pour résoudre mon problème, cependant pour vous donner une idée générale de leur forme :
    • id_article / id_parution (int, IA)
    • texte_article / texte_parution (text)
    • date_article / date_parution (date)


    Toujours là? :p
    Alors voici ce que j'aimerais faire : une requête allant chercher chaque thème et me donnant les informations suivantes : son id (id_theme), son nom (nom_theme) et finalement le nombre d'articles et de parutions (un seul nombre, la somme des 2) associés à chaque thème. Je vais finalement les mettre dans un foreach et les afficher sous forme de tableau :

    Nom du thème Nombre d'articles et parutions associés
    <a href="?id=1">Justice</a> 74
    <a href="?id=2">Éducation</a> 53


    J'ai l'impression que c'est avec COUNT DISTINCT . Cependant, je ne suis pas vraiment familier avec ce dernier et ma recherche avant de me résigner à poster un message n'a pas porté fruit.

    Merci infiniment!
    • Partager sur Facebook
    • Partager sur Twitter
      20 avril 2010 à 3:39:27

      SELECT t.id_theme, t.nom_theme, COUNT(*) as nbr 
      FROM themes t 
      JOIN jonction_theme_parutions p 
          ON p.id_theme = t.id_theme 
      JOIN jonction_theme_articles a 
          ON a.id_theme = t.id_theme 
      GROUP BY id_theme
      


      Une requête comme celle-ci pourrait-elle fonctionner ? C'est difficile de faire des tests (en fait, j'ai la flemme de faire des tables et d'insérer des résultats), mais tu peux regarder dans cette optique.
      • Partager sur Facebook
      • Partager sur Twitter
        20 avril 2010 à 4:08:17

        Salut Fayden,

        Premièrement, merci de ta réponse.
        J'ai essayé ta requête. Cependant il y a deux problèmes avec cette dernière :
        • 1. Elle ne renvoie que les deux premiers thèmes;
        • 2. le COUNT ne compte que les articles avec ce thème, il ne compte pas les parutions.


        Cependant, je sens que je suis dans la bonne voie. Je vais travailler sur cette requête.

        Merci encore!
        • Partager sur Facebook
        • Partager sur Twitter
          20 avril 2010 à 4:10:46

          Peux-tu donner le CREATE TABLE des trois tables et un petit jeu d'essai ? J'aimerais faire des tests, je trouve étrange que la requête ne retourne que deux thèmes.
          • Partager sur Facebook
          • Partager sur Twitter
            20 avril 2010 à 4:16:41

            Table "themes"


            CREATE TABLE IF NOT EXISTS `themes` (
              `id_theme` int(11) NOT NULL AUTO_INCREMENT,
              `nom_theme` varchar(50) NOT NULL,
              PRIMARY KEY (`id_theme`)
            ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
            
            INSERT INTO `themes` (`id_theme`, `nom_theme`) VALUES
            (1, 'Site du Zéro'),
            (2, 'Éducation'),
            (3, 'Politique'),
            (4, 'Économie'),
            (5, 'Religion'),
            (6, 'Société');
            

            Table "jonction_themes_articles"


            CREATE TABLE IF NOT EXISTS `jonction_themes_articles` (
              `id_jonction_them_art` int(11) NOT NULL AUTO_INCREMENT,
              `id_theme` int(11) NOT NULL,
              `id_article` int(11) NOT NULL,
              PRIMARY KEY (`id_jonction_them_art`)
            ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=16 ;
            
            INSERT INTO `jonction_themes_articles` (`id_jonction_them_art`, `id_theme`, `id_article`) VALUES
            (6, 1, 3),
            (5, 1, 2),
            (4, 1, 1),
            (7, 2, 5),
            (8, 2, 6),
            (9, 2, 7),
            (10, 3, 8),
            (11, 4, 9),
            (12, 5, 10),
            (13, 1, 11),
            (14, 6, 4),
            (15, 6, 10);
            

            Table "jonction_themes_parutions"


            CREATE TABLE IF NOT EXISTS `jonction_themes_parutions` (
              `id_jonction_them_par` int(11) NOT NULL AUTO_INCREMENT,
              `id_theme` int(11) NOT NULL,
              `id_parution` int(11) NOT NULL,
              PRIMARY KEY (`id_jonction_them_par`)
            ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
            
            INSERT INTO `jonction_themes_parutions` (`id_jonction_them_par`, `id_theme`, `id_parution`) VALUES
            (2, 1, 1),
            (3, 2, 2);
            
            • Partager sur Facebook
            • Partager sur Twitter
              20 avril 2010 à 4:41:54

              En fait, j'ai fait des tests avec des tables similaires, mais je crois avoir réussi à faire un truc potable avec des sous-requêtes. Y'a peut-être (voire même probablement) moyen de faire plus simple, mais au moins, ça marche :-p

              SELECT t.id_theme, t.nom_theme, COALESCE(p.parNbr,0) + COALESCE(a.artNbr,0) as nbr 
              FROM themes t 
              LEFT JOIN (
                      SELECT id_theme, COUNT(*) as parNbr 
                      FROM jonction_themes_parutions GROUP BY id_theme
                      ) p 
                  ON p.id_theme = t.id_theme 
              LEFT JOIN (
                      SELECT id_theme, COUNT(*) as artNbr 
                      FROM jonction_themes_articles a GROUP BY id_theme
                      ) a 
                  ON a.id_theme = t.id_theme;
              


              Voici les tables :

              mysql> SELECT * FROM themes;
              +----------+-----------+
              | id_theme | nom_theme |
              +----------+-----------+
              |        1 | rouge     |
              |        2 | vert      |
              |        3 | bleu      |
              |        4 | mauve     |
              |        5 | jaune     |
              +----------+-----------+
              
              mysql> SELECT * FROM jonction_themes_parutions;
              +-------------+----------+-------------+
              | id_jonction | id_theme | id_parution |
              +-------------+----------+-------------+
              |           1 |        1 |         100 |
              |           2 |        1 |         101 |
              |           3 |        1 |         102 |
              |           4 |        2 |         103 |
              |           5 |        2 |         104 |
              |           6 |        3 |         105 |
              +-------------+----------+-------------+
              
              mysql> SELECT * FROM jonction_themes_articles;
              +-------------+----------+------------+
              | id_jonction | id_theme | id_article |
              +-------------+----------+------------+
              |           1 |        1 |        200 |
              |           2 |        1 |        201 |
              |           3 |        2 |        202 |
              |           4 |        4 |        203 |
              +-------------+----------+------------+


              Le résultat de la requête :
              +----------+-----------+------+                                                                                                                                                                            
              | id_theme | nom_theme | nbr  |                                                                                                                                                                            
              +----------+-----------+------+                                                                                                                                                                            
              |        1 | rouge     |    5 |                                                                                                                                                                            
              |        2 | vert      |    3 |                                                                                                                                                                            
              |        3 | bleu      |    1 |                                                                                                                                                                            
              |        4 | mauve     |    1 |                                                                                                                                                                            
              |        5 | jaune     |    0 |                                                                                                                                                                            
              +----------+-----------+------+

              Donc bref, si quelqu'un trouve mieux, je suis aussi preneur.
              • Partager sur Facebook
              • Partager sur Twitter
                20 avril 2010 à 4:45:52

                Wow! Compliqué tout ça!

                Juste par curiosité, où as-tu appris à faire ce genre de requêtes avancées? S'il existait un livre ou un tutoriel sur le web, je serais vraiment intéressé.

                Bref, merci beaucoup de ton aide! Ça fonctionne chez moi aussi!

                Martin
                • Partager sur Facebook
                • Partager sur Twitter
                  20 avril 2010 à 4:49:48

                  C'est pas très avancé (surtout que j'imagine qu'il est possible de faire plus simple, mais j'ai pas réussi sans tables temporaires), il suffit simplement de connaître les différentes syntaxes.

                  Si tu sais faire une table temporaire (ma sous-requête) et que tu sais comment faire des jointures, tu peux associer tout ensemble, et ça permet de faire ce genre de trucs.

                  J'ai lu des trucs un peu partout sur le net (surtout au niveau des jointures), je fais des tests (j'ai pas pondu ça en 2 minutes :-p) et je persévère quand ça marche pas. Un peu comme n'importe quoi.

                  Enfin, si j'ai un site à conseiller, c'est bien celui de sqlpro. C'est un excellent site rédigé par un professionnel.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    20 avril 2010 à 4:56:38

                    C'est tout juste ce que j'avais besoin!

                    Merci beaucoup!
                    • Partager sur Facebook
                    • Partager sur Twitter

                    [MySQL] Requête avec tables multiples et jointures

                    × 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