[RESOLU] Afficher nombre d'articles par catégories - avec group by

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : [RESOLU] Afficher nombre d'articles par catégories - avec group by

Re: [RESOLU] Afficher nombre d'articles par catégories - avec group by

par stephweb » 14 oct. 2015, 20:34

Bonjour,
j'avais cliqué sur résolu trop top… Y a un dernier problème auquel je n'avais pas pensé. Dans ma page où je gère mes catégories, j'ai un Search pour afficher la liste des catégories WHERE LIKE mots clés entrés. Et je ne sais pas où placer le LIKE dans ce code:

Code : Tout sélectionner

<?php /* * categories : Table des catégories qui peuvent etre reliées à des articles * articles : Table des articles * categories_jointes_articles : Table pivot (qui a comme champs id_article et id_categorie) */ $sql = "SELECT categories.id, categories.nom , COUNT(articles.id) as nb_articles FROM categories"; // si je met WHERE categories.nom LIKE ? ici, // PDO me renvoi erreur $sql .= " LEFT OUTER JOIN categories_jointes_articles ON categories.id = categories_jointes_articlesid_categorie LEFT OUTER JOIN articles ON articles.id = categories_jointes_articles.id_article"; $sql .= " AND articles.statut = ? "; // Si je met mle LIKE ici, toutes mes catégories s'affichent // quelques soit les mots clés entrés $sql .= " GROUP BY categories.id, categories.nom "; $requete = self::getDb()->prepare($sql); // bindValue du statut $requete->bindValue(1, 1, PDO::PARAM_INT); // bindValue des mots clés entrés $requete->bindValue(2, '%'.$motsQ.'%', PDO::PARAM_STR); $requete->execute(); $requete->setFetchMode(PDO::FETCH_OBJ); return $requete;
Cette ligne :

Code : Tout sélectionner

$sql .= " AND categories.nom LIKE ? ";
Je ne sais pas où la mettre. Si je le met juste après le FROM, PDO me renvoi cette erreur: " Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' in …"

si je la met juste avant le GROUP BY, toutes mes catégories s'affichent quelques soit les mots clés entrés.
ça fait un bon moment que je galère, et dans Google je ne trouve rien de similaire à mon problème.
Merci beaucoup.

Re Edit:
Ok merci. J'ai remplacé :

Code : Tout sélectionner

$sql .= " AND categories.nom LIKE ? ";
par :

Code : Tout sélectionner

$sql .= " WHERE categories.nom LIKE ? ";
Visiblement ça fonctionne. merci

Re: Afficher nombre d'articles par catégories - avec group by

par stephweb » 13 oct. 2015, 13:48

Du coup, sujet résolu avec ce code:

Code : Tout sélectionner

$sql = "SELECT ".$this->_tableCategoriesArticles.".id, ".$this->_tableCategoriesArticles.".nom , COUNT(".$this->_tableArticles.".id) as nb_articles FROM ".$this->_tableCategoriesArticles." LEFT OUTER JOIN ".$this->_tableCategoriesJointesArticles." ON ".$this->_tableCategoriesArticles.".id = ".$this->_tableCategoriesJointesArticles.".id_categorie LEFT OUTER JOIN ".$this->_tableArticles." ON ".$this->_tableArticles.".id = ".$this->_tableCategoriesJointesArticles.".id_article AND ".$this->_tableArticles.".statut = :statut GROUP BY ".$this->_tableCategoriesArticles.".id, ".$this->_tableCategoriesArticles.".nom"; $requete = self::getDb()->prepare($sql); $requete->bindValue(':statut', 1, PDO::PARAM_INT); $requete->execute(); $requete->setFetchMode(PDO::FETCH_OBJ); return $requete;
Merci à tous

Re: Afficher nombre d'articles par catégories - avec group by

par yann18 » 13 oct. 2015, 13:00

ça m'affiche uniquement les catégories qui sont reliés à des articles... ça ne m'affiche pas les catégories qui ne sont pas reliées à des articles.
le fait de filtrer uniquement les articles ayant un statut 1 implique la sélection des articles qui sont forcement rattachés à une catégorie.Pour récupérer toutes les catégories( y compris celles qui n'ont pas d'articles) il faut aussi récupérer les statuts d'articles qui ne retourne rien c-a-d null.
Juste ajouter le critère OR:
"OR statut IS NULL";

Re: Afficher nombre d'articles par catégories - avec group by

par stephweb » 13 oct. 2015, 11:34

Ok merci.
ça fonctionne uniquement si j'enlève la 2ème jointure.
Mais avec ce code (avec la 2è jointure avec la table articles pour ajouter un WHERE statut) :

Code : Tout sélectionner

<?php $sql = "SELECT ".$this->_tableCategoriesArticles.".id, ".$this->_tableCategoriesArticles.".nom , COUNT(id_article) as nb_articles FROM ".$this->_tableCategoriesArticles." LEFT OUTER JOIN ".$this->_tableCategoriesJointesArticles." ON ".$this->_tableCategoriesArticles.".id = ".$this->_tableCategoriesJointesArticles.".id_categorie LEFT OUTER JOIN ".$this->_tableArticles." ON ".$this->_tableArticles.".id = ".$this->_tableCategoriesJointesArticles.".id_article WHERE ".$this->_tableArticles.".statut = :statut GROUP BY ".$this->_tableCategoriesArticles.".id, ".$this->_tableCategoriesArticles.".nom"; $requete = self::getDb()->prepare($sql); $requete->bindValue(':statut', 1, PDO::PARAM_INT); $requete->execute(); $requete->setFetchMode(PDO::FETCH_OBJ); return $requete;
ça m'affiche uniquement les catégories qui sont reliés à des articles... ça ne m'affiche pas les catégories qui ne sont pas reliées à des articles.
J'ai essayé de remplacer les LEFT par des RIGHT, ou de remplacer le 2è LEFT paru n INNER... mais ça ne change rien.

Re: Afficher nombre d'articles par catégories - avec group by

par Ryle » 13 oct. 2015, 09:22

Le COUNT(*) va effectivement compter le nombre d'enregistrements, il suffit à priori juste de remplacer celui-ci par un COUNT(id_article) pour ne compter que ces derniers :)

(il faudra peut être préfixer le nom de la colonne par le nom de la table)

Re: Afficher nombre d'articles par catégories - avec group by

par stephweb » 12 oct. 2015, 20:26

Ok merci;
j'ai essayé ceci:

Code : Tout sélectionner

$sql = "SELECT ".$this->_tableCategoriesArticles.".id, ".$this->_tableCategoriesArticles.".nom , COUNT(*) as nb_articles FROM ".$this->_tableCategoriesArticles." LEFT OUTER JOIN ".$this->_tableCategoriesJointesArticles." ON ".$this->_tableCategoriesArticles.".id = ".$this->_tableCategoriesJointesArticles.".id_categorie GROUP BY ".$this->_tableCategoriesArticles.".id, ".$this->_tableCategoriesArticles.".nom ORDER BY id DESC"; $requete = self::getDb()->prepare($sql); $requete->execute(); $requete->setFetchMode(PDO::FETCH_OBJ); return $requete;
Avec ceci, ça m'affiche toute mes catégories. Mais pour mes catégories qui n'ont aucun article, ça m'affiche 1 ou lieu de 0 pour le count (comme quoi mes catégories qui sont sans article ont 1 article, ce qui est évidement pas le cas...).
Si je remplace LEFT OUTER JOIN par RIGHT OUTER JOIN, ça m'affiche seulement mes catégories ayant des articles (donc ça ne change rien par rappoet au INNER JOIN).
J'ai fait une erreur?
Merci

Re: Afficher nombre d'articles par catégories - avec group by

par Ryle » 12 oct. 2015, 18:28

Oui c'est possible avec des jointures externes (OUTER JOIN) au lieu de jointure interne. Ainsi même s'il n'y a pas de correspondance dans la table jointe, tu auras quand même un enregistrement de retourné (et le count indiquera zéro :))

Re: Afficher nombre d'articles par catégories - avec group by

par stephweb » 12 oct. 2015, 16:32

Ok Exact, merci. Va falloir que je révise les jointures...

Il reste un dernier problème, ça ne m'affiche pas tout les catégories. ça m'affiche uniquement les catégories qui sont reliées à des articles.
C'est normal ? Y'a t-il un moyen, dans la liste des catégories d'afficher toutes les catégories (y compris celles qui ne sont pas reliées à des articles) ?
Merci

Re: Afficher nombre d'articles par catégories - avec group by

par Ryle » 12 oct. 2015, 16:19

Il te faut faire une jointure avec ta table d'articles pour pouvoir interroger et contrôler les statuts.

Quelque chose du genre :
"INNER JOIN ".$this->_tableArticles."
  ON ".$this->_tableArticles.".id = ".$this->_tableCategoriesJointesArticles.".id_article"
A adapter en fonction de tes noms de tables et de champs

Tu pourras alors ajouter ta clause WHERE sur le statut à prendre en compte (ou utiliser un IN (x,y,z) pour plusieurs statuts)

Ex :
$sql = "SELECT ".$this->_tableCategoriesArticles.".id, ".$this->_tableCategoriesArticles.".nom
         , COUNT(*) as nb_article 
   FROM ".$this->_tableCategoriesArticles."
   INNER JOIN ".$this->_tableCategoriesJointesArticles."
      ON ".$this->_tableCategoriesArticles.".id = ".$this->_tableCategoriesJointesArticles.".id_categorie
  INNER JOIN ".$this->_tableArticles."
      ON ".$this->_tableArticles.".id = ".$this->_tableCategoriesJointesArticles.".id_article
      WHERE ".$this->_tableArticles.".statut = :statut
   GROUP BY ".$this->_tableCategoriesArticles.".id, ".$this->_tableCategoriesArticles.".nom";

Re: Afficher nombre d'articles par catégories - avec group by

par stephweb » 12 oct. 2015, 14:38

En fait,fa llais que je remplace ".$this->_tableCategoriesJointesArticles.".id_articlepar ".$this->_tableCategoriesJointesArticles.".id_categorie.

Par contre, le fait d'utiliser un GROUP BY, ça me pose un autre problème.
Car ça m'affiche le nombre d'articles par catégorie, OK. Mais le problème c'est que j'ai des articles avec le statut publié, d'autre en brouillons, d'autre dans la corbeille...
Comment puisje faire pour que je suis ajouter un WHERE statut à ce code ? :

Code : Tout sélectionner

/* * Requete SQL SELECT pour récupérer la liste des catégories, * et aussi récupérer le nombre d'article par catégorie4 * @param statut - 1: Articles publiés, 2 : articles en brouillons, 3: articles dans la corbeille */ public function selectListeCategories($statut) { $sql = "SELECT ".$this->_tableCategoriesArticles.".id, ".$this->_tableCategoriesArticles.".nom , COUNT(*) as nb_article FROM ".$this->_tableCategoriesArticles." INNER JOIN ".$this->_tableCategoriesJointesArticles." ON ".$this->_tableCategoriesArticles.".id = ".$this->_tableCategoriesJointesArticles.".id_categorie GROUP BY ".$this->_tableCategoriesArticles.".id, ".$this->_tableCategoriesArticles.".nom"; $requete = self::getDb()->prepare($sql); $requete->execute(); $requete->setFetchMode(PDO::FETCH_OBJ); return $requete; } /* $this->_tableCategoriesArticles : Est ma table où il y a mes catégories (que je peut relier à mes articles) $this->_tableArticles : Est ma table où il y a mes articles $this->_tableCategoriesJointesArticles : Est ma table intermédaire, qui relie ma table articles à ma table categories */
Il me faudrai un truc comme ceci:

Code : Tout sélectionner

public function selectListeCategories($statut) { $sql = "SELECT ".$this->_tableCategoriesArticles.".id, ".$this->_tableCategoriesArticles.".nom , COUNT(*) as nb_article FROM ".$this->_tableCategoriesArticles." INNER JOIN ".$this->_tableCategoriesJointesArticles." ON ".$this->_tableCategoriesArticles.".id = ".$this->_tableCategoriesJointesArticles.".id_categorie WHERE dans la table articles statut = :statut GROUP BY ".$this->_tableCategoriesArticles.".id, ".$this->_tableCategoriesArticles.".nom"; $requete = self::getDb()->prepare($sql); $requete->bindValue(':statut', $statut, PDO::PARAM_INT); $requete->execute(); $requete->setFetchMode(PDO::FETCH_OBJ); return $requete; }
Mais je n'arrive pas à le finaliser.
Merci beaucoup

Re: Afficher nombre d'articles par catégories - avec group by

par stephweb » 12 oct. 2015, 13:26

Ok merci. J'ai mis ton GROUP by, mais visiblement ça ne fonctionne pas correctement. ça m'affiche que mes catégories ont chacune 1 article, alors qu'elles n'ont pas qu'1 seul article.

Re: Afficher nombre d'articles par catégories - avec group by

par Ryle » 12 oct. 2015, 11:22

Bonjour,

La clause GROUP BY doit lister l'ensemble des colonnes non groupées de ta requête :
GROUP BY ".$this->_tableCategoriesArticles.".id, ".$this->_tableCategoriesArticles.".nom
Et puisque le nombre d'éléments est retourné dans la requête pour chaque enregistrement avec l'alias nb_artible, il suffit simplement de lire celui-ci :
echo '<option value="' . $data_cat->id . '">' . $data_cat->nom . ' (' . $data_cat->nb_article . ')</option>';

Afficher nombre d'articles par catégories - avec group by

par stephweb » 12 oct. 2015, 10:22

Bonjour, je viens demander de l'aide Svp.

Dans un CMS fait maison, j'ai une page qui affiche la liste des articles, et dans cette page il y a un select pour pouvoir filtrer par catégorie.
Et dans ce select, j'affiche entre des parenthèses le nombre d'articles que chaque catégorie contient.
Voici en image : http://www.creerwebsite.com/medias/uplo ... _testp.png

Voici mon Code actuel:
HTML:

Code : Tout sélectionner

<form id="form-categories" action="#" method="get"> <select onchange="document.getElementById('form-categories').submit();" name="categorie"> <?php // ** req SQL SELECT pour récup liste des catégories ** $data = $categorieArticle->selectListeCategories(); foreach($data as $data_cat) { // ** req SQL COUNT pour afficher nombre d'articles par catégorie (entre les parenthèse, dans <select>) ** $data_count = $article->nbArticlesParCategorie($data_cat->id); echo '<option value="'.$data_cat->id.'">'.$data_cat->nom.' ('.$data_count.')</option>'; } ?> </select> </form>
PHP (dans ma Classe "CategorieArticle") :

Code : Tout sélectionner

<?php /** * Requete SQL SELECT pour récupérer la liste des catégories */ public function selectListeCategories() { $sql = "SELECT * FROM ".$this->_tableCategoriesArticles.""; $requete = self::getDb()->prepare($sql); $requete->execute(); $requete->setFetchMode(PDO::FETCH_OBJ); return $requete; /* $this->_tableCategoriesArticles : Est ma table où il y a mes catégories (que je peut relier à mes articles) */ }
PHP (dans ma Classe "Article") :

Code : Tout sélectionner

<?php /** * Requete SQL SELECT COUNT pour affiher le nombre d'articles par catégorie (entre les parenthèse, dans <select>) */ public function nbArticlesParCategorie($id_cat) { $sql = "SELECT COUNT(*) as nb FROM ".$this->_tableArticles." INNER JOIN ".$this->_tableCategoriesJointesArticles." ON ".$this->_tableArticles.".id = ".$this->_tableCategoriesJointesArticles.".id_article"; "WHERE ".$this->_tableCategoriesJointesArticles.".id_categorie = :id_cat"; $requete = self::getDb()->prepare($sql); $requete->bindValue(':id_cat', $id_cat); $requete->execute(); $result = $requete->fetch(PDO::FETCH_OBJ); $requete->closeCursor(); return (int) $result->nb; } /* $this->_tableArticles : Est ma table où il y a mes articles $this->_tableCategoriesJointesArticles : Est ma table intermédaire, qui relie ma table articles à ma table categories */
Le problème, avec ce code, si par exemple il y a 50 catégories, ça me fait faire 50 requêtes SQL COUNT…
Donc j'aimerai bien utiliser un "GROUP BY";

Voici mon nouveau code que je n'arrive pas à faire fonctionner:

Code : Tout sélectionner

<?php /** * Avec ce code, je souhaite à la fois récupérer la liste des catégories, * et aussi afficher le nombre d'article que cette catégorie contient */ public function selectListeCategories() { $sql = "SELECT ".$this->_tableCategoriesArticles.".id, ".$this->_tableCategoriesArticles.".nom , COUNT(*) as nb_article FROM ".$this->_tableCategoriesArticles." INNER JOIN ".$this->_tableCategoriesJointesArticles." ON ".$this->_tableCategoriesArticles.".id = ".$this->_tableCategoriesJointesArticles.".id_article GROUP BY ".$this->_tableCategoriesArticles.".id"; $requete = self::getDb()->prepare($sql); $requete->execute(); $requete->setFetchMode(PDO::FETCH_OBJ); return $requete; }
Mais pour le moment ce code, m'affiche uniquement ma liste de catégories, je ne sais pas comment faire avec ce code pour aussi afficher le nombre d'articles que chaque catégorie contient;

Merci beaucoup.