Partage

[MySQL] Requête avec tables multiples et jointures

Sujet résolu
Le 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!
Publicité
Le 20 avril 2010 à 3:22:16
Le 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.
Le 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!
Le 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.
Le 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);
Le 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.
Le 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
Le 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.
Le 20 avril 2010 à 4:56:38

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

Merci beaucoup!

[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é.
  • Editeur
  • Markdown