Partage
  • Partager sur Facebook
  • Partager sur Twitter

Requête interne

Requêteur chevronné, à vous de jouer !

Sujet résolu
    23 novembre 2010 à 23:14:26

    Bonsoir les Zéros,

    Je galère un petit peu sur une requête un peu particulière (selon moi), j'aimerais avoir un coup de main si possible.

    Tout d'abord, les deux tables concernées :

    --
    -- Structure de la table `category`
    --
    
    CREATE TABLE IF NOT EXISTS `category` (
      `id_category` int(11) NOT NULL AUTO_INCREMENT,
      `title` varchar(255) COLLATE utf8_bin NOT NULL,
      `position` int(5) NOT NULL,
      `visible` tinyint(1) NOT NULL,
      PRIMARY KEY (`id_category`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=4 ;
    
    --
    -- Structure de la table `news`
    --
    
    CREATE TABLE IF NOT EXISTS `news` (
      `id_news` int(11) NOT NULL AUTO_INCREMENT,
      `title` varchar(255) COLLATE utf8_bin NOT NULL,
      `date_create` datetime NOT NULL,
      `date_update` datetime NOT NULL,
      `date_publish` datetime NOT NULL,
      `content` text COLLATE utf8_bin NOT NULL,
      `position` int(5) NOT NULL,
      `visible` tinyint(1) NOT NULL,
      `id_category` int(11) NOT NULL,
      `id_user_create` int(11) NOT NULL,
      `id_user_update` int(11) DEFAULT NULL,
      PRIMARY KEY (`id_news`),
      KEY `id_category` (`id_category`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=6 ;
    


    Ce que j'aimerais, c'est avoir la liste complète des 'category' (avec tous les champs) avec le nombre de 'news' associée à chaque 'category' en plus, le tout ordonné par le champ 'position' dans l'ordre croissant.
    Voila en console ce que j'aimerais pouvoir retourner.
    +-------------+--------------+----------+---------+---------+
    | id_category | title        | position | visible | nb_news |
    +-------------+--------------+----------+---------+---------+
    |           1 | Web 2.0      |        0 |       1 |       0 |
    |           2 | Culture      |        1 |       0 |       0 |
    |           3 | Site du Zéro |        5 |       1 |       1 |
    +-------------+--------------+----------+---------+---------+


    J'ai réussi à monter cette requête, mais elle ne me retourne qu'une seule ligne de résultat :


    SELECT c.*, COUNT(*) AS nb_news FROM news n, category c WHERE c.id_category = n.id_category GROUP BY c.id_category ORDER BY c.position;
    


    Elle retourne pas les lignes dont le nombre de news associées est à 0, or j'aimerais qu'il m'indique 0 quand même.

    Auriez vous la solution Zéros chevronnés ? =)

    Merci d'avance !
    • Partager sur Facebook
    • Partager sur Twitter
      23 novembre 2010 à 23:33:58

      C'est pareil qu'un forum en fait.

      Solution simple : utilise un LEFT JOIN.
      Solution rapide : stocke le nombre de news dans la table catégories.
      • Partager sur Facebook
      • Partager sur Twitter
        23 novembre 2010 à 23:45:02

        Comment est-ce que tu monte cela avec LFET JOIN, je n'y arrive pas personnellement. :(
        Merci
        • Partager sur Facebook
        • Partager sur Twitter
          23 novembre 2010 à 23:46:25

          SELECT category.id_category,title, position, visible, coalesce(nombre, 0) as 'nombre de news' 
          FROM category left join 
          (select count(id_news) as nombre, id_category from news) as A 
          ON A.id_category = category.id_category
          ORDER BY category.position
          


          Ce code devrait fonctionner même si c'est pas forecement la solution la plus simple et la plus directe...

          Comme l'a dit Casque Noir, il faut chercher du côté des LEFT JOIN :)
          • Partager sur Facebook
          • Partager sur Twitter
            24 novembre 2010 à 0:02:20

            Merci de votre aide.
            Mastache, ta requête fonctionne mais pas entièrement, j'ai une sorte de COUNT global dont le résultat (qui est le nombre total de news) est en première ligne.

            SELECT c.id_category, c.title, c.position, c.visible, COALESCE(nombre, 0) AS nb_news
            FROM category c
            LEFT JOIN (
            	SELECT COUNT(id_news) AS nombre, id_category
            	FROM news) AS A
            ON A.id_category = c.id_category
            ORDER BY c.position;
            


            +-------------+--------------+----------+---------+---------+
            | id_category | title        | position | visible | nb_news |
            +-------------+--------------+----------+---------+---------+
            |           1 | Web 2.0      |        0 |       1 |       3 |
            |           2 | Geek         |        1 |       0 |       0 |
            |           3 | Site du ZÚro |        5 |       1 |       0 |
            +-------------+--------------+----------+---------+---------+


            Alors que j'ai 2 news avec id_category à 1, et une news avec id_category à 3 (et 0 pour l'id 2)

            Sinon je n'arrive vraiment pas avec LEFT JOIN, pouvez-vous continuer de m'aiguiller svp ?

            Merci beaucoup !
            • Partager sur Facebook
            • Partager sur Twitter
              24 novembre 2010 à 0:15:25

              Il manque un GROUP BY id_category dans la sous-requête.
              • Partager sur Facebook
              • Partager sur Twitter
                24 novembre 2010 à 0:17:39

                Jolie Fayden !
                C'est exactement ça, la requête fonctionne ! Merci !

                SELECT c.*, COALESCE(nb, 0) AS nb_news
                FROM category c
                LEFT JOIN (
                	SELECT id_category, COUNT(*) AS nb
                	FROM news
                	GROUP BY id_category
                ) AS n
                ON c.id_category = n.id_category
                ORDER BY c.position;
                
                • Partager sur Facebook
                • Partager sur Twitter

                Requête interne

                × 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