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 :

recuperation data sur une query complexe


Sujet :

ORM PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Par défaut recuperation data sur une query complexe
    Bonjour a tous,
    J'ai encore un peu de mal a comprendre comment fonctionne Doctrine.

    j'ai une requete quelque peu complexe:
    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
    $q=$this->createQuery('s')
                    ->select('s.id,u.id,  c.id, f.id, f1.name as formation, f1.periodicite,
                        MAX(fu.date) as datemax,
                        IF(
                           (CURRENT_DATE() <= TIMESTAMPADD(MONTH, f1.periodicite, max(fu.date)))
                           ||
                           (f1.periodicite=0 && MAX(fu.date) IS NOT NULL),
                           0,
                           1
                           ) as result')
                    ->leftJoin('s.classifications u')
                    ->leftJoin('u.class c')
                    ->leftJoin('c.list_formation f')
                    ->leftJoin('f.formation f1')
                    ->leftJoin('s.formations fu ON s.id=fu.user_id AND fu.formation_id=f1.id')
                    ->where('s.id=?',$user_id)
                    ->groupBy('s.id, u.id,  c.id, f.id, f1.name')              
                    ;
    $data=$q->execute()
    je voudrait récuperer dans un foreach
    quelque chose du type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    foreach($data as $line)
    {
      echo $line->getFormation().' '.$line->getDatemax().' '.$line->getResult().'<br>';
    }
    pour le moment ce code ne m'affiche que la premiere ligne.
    Hors le code SQL m'affiche bien la totalité de mes enregistrements.

  2. #2
    Membre éclairé
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Par défaut
    bon en modifiant mon code :
    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
     
    $q=$this->createQuery('s')
                    ->select('s.id,u.id,  c.id, f.id, f1.name as forma, f1.periodicite,                    
                        IF(
                           (CURRENT_DATE() <= TIMESTAMPADD(MONTH, f1.periodicite, max(fu.date)))
                           ||
                           (f1.periodicite=0 && MAX(fu.date) IS NOT NULL),
                           0,
                           1
                           ) as result,
                           MAX(fu.date) as maximum')
                    ->leftJoin('s.classifications u')
                    ->leftJoin('u.class c')
                    ->leftJoin('c.list_formation f')
                    ->leftJoin('f.formation f1')
                    ->leftJoin('s.formations fu ON s.id=fu.user_id AND fu.formation_id=f1.id')
                    ->having('s.id=?',$user_id)
                    ->groupBy('s.id, u.id,  c.id, f.id, f1.name')
                    ->execute(array(), Doctrine::HYDRATE_ARRAY)
                    ;
            $data=$q;
    et avec cette boucle :
    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
    foreach($data as $classifications)
            {                        
                foreach($classifications['classifications'] as $classification )
                {                
                    foreach($classification['class'] as $formations)
                    {
     
                       if(is_array($formations))
                       {
                           foreach($formations as $formation)
                           {
                               var_dump($formation['formation']);
                           }
                       }                   
                    }
                }
            }
    j'obtient ceci
    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
    26
    27
    28
    29
    30
    array
      'id' => string '16' (length=2)
      'periodicite' => string '0' (length=1)
      'forma' => string 'gestes et postures charges lourdes' (length=34)
      'result' => string '0' (length=1)
     
    --------------------------------------------------------------------------------
     
    --------------------------------------------------------------------------------
     
    array
      'id' => string '5' (length=1)
      'periodicite' => string '12' (length=2)
      'forma' => string 'ESHEM-121' (length=9)
      'result' => string '0' (length=1)
    array
      'id' => string '6' (length=1)
      'periodicite' => string '0' (length=1)
      'forma' => string 'PWT Préparation au Quizz P.L.A.T.O.' (length=36)
      'result' => string '1' (length=1)
    array
      'id' => string '7' (length=1)
      'periodicite' => string '0' (length=1)
      'forma' => string 'Quizz P.L.A.T.O.' (length=16)
      'result' => string '1' (length=1)
    array
      'id' => string '8' (length=1)
      'periodicite' => string '12' (length=2)
      'forma' => string 'check list home office' (length=22)
      'result' => string '1' (length=1)
    comme vous pouvez le voir, si j'ai bien mon champ result impossible d'obtenir mon champ maximum.
    Si quelqu'un a une idée ?

  3. #3
    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
    Du mal avec doctrine ? Mais non !

    Fais un var_dump des données de ton premier query et tu devrais comprendre ce qui cloche.

    Accessoirement, il existe plusieurs méthode d'hydratation qui, si elles retournent les mêmes données, ne les retournent pas dans la même structure. Quelques essais avec quelques print_r ou apparenté devraient te permettre de bien visualiser les choses. Et de trouver la meilleur méthode pour ton cas.

  4. #4
    Membre éclairé
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Par défaut
    un var_dump du query initial me donne bien mon champ mais seulement pour le premier enregistrement

  5. #5
    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
    Essaye avec les différents type hydratation a mon avis tu devrais récupérer les données.

  6. #6
    Membre éclairé
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Par défaut
    bon apparemment la seul manière de récupérer des données d'une query un peu complexe c'est avec un Hydrate_NONE.

    vois pas trop la puissance de doctrine la

  7. #7
    Membre éclairé
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Par défaut recupercation champ custom
    j'ai une requet DQL qui me donne un SQL correcte:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $q=$this->createQuery('a')
                    ->select('a.*,sf.*,se.*,ga.id,a1.*,hi1.*')
                    ->addSelect('hi2.total as prevtotal')
                    ->leftJoin('a.users sf')
                    ->leftJoin('sf.Costcenter se')
                    ->leftJoin('sf.groupassets ga')
                    ->leftJoin('ga.listGroupAsset a1 ON a1.groupasset_id=ga.id AND a1.type="email"')
                    ->innerJoin('a1.historic hi1 ON hi1.asset_id=a1.id AND hi1.datestate="'.$datelimit.'"')
                    ->leftJoin('a1.historic hi2 ON hi2.asset_id=a1.id AND hi2.datestate="'.$predate.'"')
                    ->where('a.id=?',$site->getId())
                    ->andWhere('sf.is_active=true')                
                    ->orderBy('se.business, se.name, sf.last_name, sf.first_name')
    le souci est comment recuperer mon champ prevTotal ?

  8. #8
    Membre émérite Avatar de kenny.kev
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    646
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 646
    Par défaut
    ton prevTotal est ton total, alors tu fais un getTotal() et tu l'as.

  9. #9
    Membre éclairé
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Par défaut
    bein non, getTotal me donne le total de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ->innerJoin('a1.historic hi1 ON hi1.asset_id=a1.id AND hi1.datestate="'.$datelimit.'"')
    comment recuperer le total de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ->leftJoin('a1.historic hi2 ON hi2.asset_id=a1.id AND hi2.datestate="'.$predate.'"')
    je rempli un tableau donc j'ai un ensemble de boucle imbriqués:
    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
     
    foreach($data as $site)
    {
       foreach($site->getUsers() as $user)
       {
           tbl[$user->getCostcenter][$user->getId()]['user']=$user;
           foreach($user->getGroupasset() as $groupeAsset)
           {
               foreach($groupasset as $asset)
               {
                   foreach($asset->gethistoric() as $historic)
                   {
                        tbl[$user->getCostcenter][$user->getId()] ['total']=$historic->getTotal() // celui de hi1
                        tbl[$user->getCostcenter]['total']+=$historic->getTotal() ;
     
                    }
                }
            }
        }
    }
    comment avoir tbl[$user->getCostcenter][$user->getId()] ['prevtotal'] ?

  10. #10
    Membre éclairé
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Par défaut
    bon pour le moment j'ai réduit ma requete
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $q=$this->createQuery('a')               
                    ->leftJoin('a.users sf')
                    ->leftJoin('sf.Costcenter se')
                    ->leftJoin('sf.groupassets ga')
                    ->leftJoin('ga.listGroupAsset a1 ON a1.groupasset_id=ga.id AND a1.type="email"')
                    ->innerJoin('a1.historic hi1 ON hi1.asset_id=a1.id AND hi1.datestate="'.$datelimit.'"')                
                    ->where('a.id=?',$site->getId())
                    ->andWhere('sf.is_active=true')                
                    ->orderBy('se.business, se.name, sf.last_name, sf.first_name')
    et j'ai modifié ma boucle:
    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
     
     
    foreach($data as $site)
    {
       foreach($site->getUsers() as $user)
       {
           tbl[$user->getCostcenter][$user->getId()]['user']=$user;
           foreach($user->getGroupasset() as $groupeAsset)
           {
               foreach($groupasset as $asset)
               {
                   foreach($asset->gethistoric() as $historic)
                   {
                        tbl[$user->getCostcenter][$user->getId()] ['total']=$historic->getTotal() // celui de hi1
                        tbl[$user->getCostcenter]['total']+=$historic->getTotal() ;
                        $prevTotal=Doctrine_core::getTable('email_diskspace')->findOneByAssetIdAndDatestate($asset->getId(), $prevDate);
                        tbl[$user->getCostcenter][$user->getId()] ['prevtotal']=$prevTotal;
     
                    }
                }
            }
        }
    }
    Mais bon je trouve pas ça trés optimisé

  11. #11
    Membre émérite Avatar de kenny.kev
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    646
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 646
    Par défaut
    Contrairement à ce que tu penses une requête avec 10 jointures n'est pas plus optimisé que 2 requêtes séparé pour obtenir le meme résultat.

    Tu peux meme faire des tests je suis presque sur que tes 2 requêtes sont plus performante que ta première requête.

    Fais aussi un explain dessus et tu verras.

Discussions similaires

  1. Bloc basé sur une vue complexe
    Par tommy_f dans le forum Forms
    Réponses: 9
    Dernier message: 19/03/2008, 14h10
  2. recuperer selection sur une liste deroulante
    Par skillipo dans le forum Servlets/JSP
    Réponses: 1
    Dernier message: 18/02/2008, 09h17
  3. Recuperation data d'une liste
    Par insa59 dans le forum GTK+ avec C & C++
    Réponses: 1
    Dernier message: 09/03/2007, 15h08
  4. Réponses: 1
    Dernier message: 19/02/2007, 12h45
  5. Update Sql sur une Query Filtré
    Par Soulama dans le forum Bases de données
    Réponses: 4
    Dernier message: 26/10/2006, 14h47

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