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

  1. #1
    Membre habitué
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Points : 178
    Points
    178
    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 habitué
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Points : 178
    Points
    178
    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 éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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
    Points : 8 486
    Points
    8 486
    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 habitué
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Points : 178
    Points
    178
    Par défaut
    un var_dump du query initial me donne bien mon champ mais seulement pour le premier enregistrement

  5. #5
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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
    Points : 8 486
    Points
    8 486
    Par défaut
    Essaye avec les différents type hydratation a mon avis tu devrais récupérer les données.

  6. #6
    Membre habitué
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Points : 178
    Points
    178
    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
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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
    Points : 8 486
    Points
    8 486
    Par défaut
    Ça doit dépendre de ce que tu veux récupérer et tu query.

    Perso, celui-là, je n'ai jamais utilisé.

  8. #8
    Membre habitué
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Points : 178
    Points
    178
    Par défaut
    bein au moins j'aurais voulu récuperer les noms de champs (HYDRATE_ARRAY),
    la c'est un vulgaire tableau indexés, j'aime pas trop.

  9. #9
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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
    Points : 8 486
    Points
    8 486
    Par défaut
    Et tu obtiens quoi avec un array_hydrate ?

  10. #10
    Membre habitué
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Points : 178
    Points
    178
    Par défaut
    un tableau a une ligne avec tout mes champs.
    Les autres lignes ne possédent que les champs existants dans le schema.

  11. #11
    Membre éclairé 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
    Points : 816
    Points
    816
    Par défaut
    Je ne sais pas si tu as résolu ton problème, mais je vais te répondre ^^.

    Pour la première question pour avoir une réponse en objet avec doctrine il te faut juste faire :
    Ça va te retourner un tableau d'objet, si je ne me trompe pas ça te donne même un objet Doctrine_collection.
    pour obtenir un tableau tu as celle que tu as récrite mais aussi avec le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $q = .... ->fetchArray()

  12. #12
    Membre habitué
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Points : 178
    Points
    178
    Par défaut
    le ..->execute() ne me renvoie mes champs perso que pour le premier enregistrement.
    Pour le fetchArray, pas tester encore

  13. #13
    Membre éclairé 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
    Points : 816
    Points
    816
    Par défaut
    test comme cela :
    http://www.doctrine-project.org/docu...having-clauses

    Tu par avec le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $q = ... ->select (count(id) as number) ->execute()
    ensuite tu fais comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    foreach ($q as $value) {
          echo $value->number;
    }
    Ça devrait fonctionner.

    Pour infos doctrine est basé sur les fonctions magique de PHP5 donc il ce peux que tu ne vois pas la méthode en faisant un var_dump.

  14. #14
    Membre habitué
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Points : 178
    Points
    178
    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 ?

  15. #15
    Membre éclairé 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
    Points : 816
    Points
    816
    Par défaut
    ton prevTotal est ton total, alors tu fais un getTotal() et tu l'as.

  16. #16
    Membre habitué
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Points : 178
    Points
    178
    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'] ?

  17. #17
    Membre habitué
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Points : 178
    Points
    178
    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é

  18. #18
    Membre éclairé 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
    Points : 816
    Points
    816
    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.

  19. #19
    Membre habitué
    Inscrit en
    Juin 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 534
    Points : 178
    Points
    178
    Par défaut
    le souci c'est que ma requête initiale je l’exécute une fois.

    La seconde je l’exécute 400 fois (1*par user)

  20. #20
    Membre éclairé 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
    Points : 816
    Points
    816
    Par défaut
    Rien ne t'empêche de regrouper ces appels pour retourner tous les résultat en une fois.

    Aussi tu as un problème quelque part, en re-regardant ce que tu avais posté 24/01/2012 17h59 et ce que tu as posté Aujourd'hui 09h27 tu as même pas la même requête.

    Analyse bien ta requête car la c'est pas la même chose.

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