IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

ORM PHP Discussion :

[Doctrine] [DQL] Problème avec sfDoctrinePager (COUNT)


Sujet :

ORM PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de Shandler
    Profil pro
    Inscrit en
    Février 2005
    Messages
    514
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 514
    Par défaut [Doctrine] [DQL] Problème avec sfDoctrinePager (COUNT)
    Bonjour,

    J'ai mis en place la pagination de symfony jusque la jai pas eut de soucis sauf que moi j'aimerais pouvoir modifier la requête que la pagination génère voir ci-dessous

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT COUNT(*) AS num_results FROM mon_texte c WHERE c.id_titre = '1'
    mais moi je voudrais ajouter ce parametre dans cette requete et j'y arrive pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT COUNT(DISTINCT c.chapitre) AS num_results FROM mon_texte c WHERE c.id_titre = '1'
    ci-dessous mon code de pagination que jai testé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $this->page = new sfDoctrinePager(
      'MonTexte',
      sfConfig::get('app_max_page')
    );
    $this->page->setQuery(Doctrine_Core::getTable('MonTexte')
    ->createQuery('c')
    ->distinct('c.chapitre')        
    ->where('c.id_titre = ?',$request->getParameter('id')));
     
    $this->page->setPage($request->getParameter('page', 1));
    $this->page->init();
    Merci a vous

  2. #2
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Ajoute dans ta requête un :
    ->select('COUNT(DISTINCT c.chapitre)')

    Cela devrait marcher (pas testé)

  3. #3
    Membre éclairé Avatar de Shandler
    Profil pro
    Inscrit en
    Février 2005
    Messages
    514
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 514
    Par défaut
    En faite j'avais déjà essayé ca mais ca ne marche pas il ne prend pas en compte le select.

    Aurais tu une autre idée ?

    Merci a toi

  4. #4
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Je pense que, pour que cela marche, il faut une clause/méthode ->groupby() avec tous les champs de la requête, sauf le champ c.chapitre.

    D'où, peut-être, l'intérêt de limiter le nombre de champs.

    J'espérais que Doctrine serait capable de la générer seul.

    Vérifie le SQL qu'il a généré, soit par un ->getQuery() à la place du execute et tu affiches par un die, soit dans les log de la barre de debug.

  5. #5
    Membre éclairé Avatar de Shandler
    Profil pro
    Inscrit en
    Février 2005
    Messages
    514
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 514
    Par défaut
    Si jai bien compris tu pense a un truc comme ca ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $this->page->setQuery(Doctrine_Core::getTable('MonTexte')
    ->createQuery('c')    
    ->where('c.id_titre = ?',$request->getParameter('id'))
    ->groupBy('c.id_titre')
    ->addgroupBy('c.page_contenu')
    ->addgroupBy('c.num_page'));
    Si oui ca me rajoute bien tous les group by dans ma requete count mais ca fait pas ce que je veux.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT COUNT(*) AS num_results FROM mon_texte c WHERE c.id_titre = '1' GROUP BY c.id_titre, c.page_contenu, c.num_page
    Merci a toi

  6. #6
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Avec le select en plus peut-être

  7. #7
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Mais je ne comprend plus alors, d'où vient la notion de compter ?

    Et pourquoi pourrait-il y avoir plusieurs chapitres identiques dans la base ?

  8. #8
    Membre éclairé Avatar de Shandler
    Profil pro
    Inscrit en
    Février 2005
    Messages
    514
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 514
    Par défaut
    Car plusieurs page peuvent être dans le même chapitre donc voila pourquoi plusieurs page peuvent avoir le même chapitre.

  9. #9
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    J'ai un peu joué.

    J'ai créé un module intitule qui m'affiche la liste des intitulés avec le nombre de chapitre (donc je compte par page distinctes). Je suis parti sur une base générée simple :
    frontend intitule intitule --non-verbose-templates --with-doctrine-route
    et une route adaptée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    intitule:
      class: sfDoctrineRouteCollection
      options:
        model:          intitule
        prefix_path:    intitule
        module:         intitule
        model_methods:
          list:         doIntitule
    le model_methods permettant d'indiquer la méthode de l'objet intituleTable à utiliser pour récupérer les données.

    La méthode rajoutée dans intituleTable
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
        public static function doIntitule()
        {
            $q = Doctrine_Query::create()
                            ->from( 'intitule i' )
                            ->leftJoin( 'i.monTexte m' )
                            ->groupBy( 'i.id' )
                            ->select( 'i.*, COUNT(DISTINCT m.num_page) AS nb_chapitre' );
            return $q->execute();
        }
    Et, pour finir joliment, le template modifier pour l'action index
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    <h1>Intitules List</h1>
     
    <table>
      <thead>
        <tr>
          <th>Id</th>
          <th>Id user</th>
          <th>Title</th>
          <th>Nb chapitre</th>
        </tr>
      </thead>
      <tbody>
        <?php foreach ($intitules as $intitule): ?>
        <tr>
          <td><a href="<?php echo url_for('intitule/edit?id='.$intitule->getId()) ?>"><?php echo $intitule->getId() ?></a></td>
          <td><?php echo $intitule->getIdUser() ?></td>
          <td><?php echo $intitule->getTitle() ?></td>
          <td><?php echo $intitule->getNbChapitre() ?></td>
        </tr>
        <?php endforeach; ?>
      </tbody>
    </table>
     
      <a href="<?php echo url_for('intitule/new') ?>">New</a>
    J'avoue que j'ai un peu galéré sur la requête qui refusait obstinément de passer. En fait, il faut utiliser un nom de champs, il n'est pas possible d'utiliser un count(m.*) par exemple. De toutes les manières, il vérifierait tous les champs et ... plouf. Vu que le texte est différents.

    Ceci répond-t-il à ta question ?

  10. #10
    Membre éclairé Avatar de Shandler
    Profil pro
    Inscrit en
    Février 2005
    Messages
    514
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 514
    Par défaut
    J'ai bien compris ta requéte sauf que la elle est pas utilisé dans la pagination de symfony et que pour mon cas le leftJoin est inutile car j'affiche le contenu de "monTexte" avec un where sur l'id de l'intitule choisi.

    Merci a toi

  11. #11
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Je dois dire que le sfPager, me sort un peu par les oreilles !

    Mais.... (roulement de tambours)

    Je pense que j'ai, enfin, la solution.

    Je reste sur mon exemple, qui ne colle pas parfaitement, l'idée est : mais comment qu'on peut récupérer ce f$#@u code select dans le sfPager).

    Il faut dans l'objet intituleTable créer une méthode qui retourne la requête ET qui prend, en paramètre un doctrine_query qui pourrait être vide...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
        public static function getIntituleDql( Doctrine_Query $q = null )
        {
            $q = ( is_null( $q ) ) ? Doctrine_Query::create()->from( 'intitule i' ) : $q;
     
            $q->leftJoin( 'i.monTexte m' )
                    ->groupBy( 'i.id' )
                    ->select( 'i.*, COUNT(DISTINCT m.num_page) AS nb_chapitre' );
            return $q;
        }
     
        public static function doIntitule()
        {
            $q = self::getIntituleDql();
            return $q->execute();
        }
    j'ai gardé la doIntitule pour vérification et compatibilité et parce que, coté code et méthode, cela peut présenter un intérêt.

    Ensuite on introduit le sfDoctrinePager dans l'action. Attention, j'ai fais un code volontairement édulcoré, il n'y a pas de gestion de la page.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
        public function executeIndex( sfWebRequest $request )
        {
            $this->intitules = new sfDoctrinePager( 'intitule', 10 );
            $this->intitules->setTableMethod( 'getIntituleDql' );
            $this->intitules->setPage( 1 );
        }
    • Création d'un objet sfDoctrinePager, on précise la table et le nombre de ligne par pages
    • On précise la méthode de l'objet du modèle qui sera utilisée pour récupérer le query
    • non utilisé ici, mais on pourrait préciser des closes complémentaire dans le query par un ->setQuery()
    • on récupère le numéro de la page et on l'indique au pager (heu, en temps normal)


    Et, avec cette méthode, miracle (heu non, logique, mais il fallait trouver), le select est correctement passé et nous retrouvons toutes les données nécessaires.

    Ouf.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2007] Problème avec columns.count
    Par issoram dans le forum Macros et VBA Excel
    Réponses: 11
    Dernier message: 29/09/2010, 16h30
  2. Problème avec un count et une imbrication
    Par zoharcryss dans le forum Langage SQL
    Réponses: 11
    Dernier message: 15/07/2009, 15h24
  3. petit problème avec un COUNT()
    Par ctobini dans le forum Requêtes
    Réponses: 4
    Dernier message: 12/12/2007, 16h53
  4. [MySQL] Problême avec un COUNT sur un template
    Par Vinuto dans le forum PHP & Base de données
    Réponses: 10
    Dernier message: 26/06/2007, 16h37
  5. [SQL] Problème avec SELECT COUNT(*)
    Par jpascal dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 17/11/2006, 12h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo