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

Doctrine2 PHP Discussion :

sous requete dans une jointure


Sujet :

Doctrine2 PHP

  1. #1
    Membre actif
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    546
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 546
    Points : 219
    Points
    219
    Par défaut sous requete dans une jointure
    Bonjour,

    Je suis avec symfony 2.3 et je voulais faire une requete un peu plus complexe avec doctrine.
    Je m'explique, j'ai une entity User(id, nom, prenom) et une entity Profile(id, id_user, annee, att1, att2)
    Entre les 2 entity j'ai une relation oneToMany avec 1 user peut avoir N Profile
    Le profile étant le profile du user avec 1 seul par année.
    Je voudrais faire une requete, du genre att1=1 mais uniquement sur les profiles les plus récent de chaque user.
    En SQL j'aurai fait comme cela :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT u.nom
    FROM profile p1
    JOIN user u on u.id = p1.id_user
    JOIN (
        SELECT MAX(p2.annee) defyear, p2.id_user
        FROM profile p2
        GROUP BY p2.id_user
    ) t2 ON p1.id = t2.id_user AND p1.annee = t2.defyear
    WHERE p1.att1 = 1
    Donc avec une sous requete dans le join.
    Mais comment faire ça avec doctrine et le querybuilder ?
    Merci de votre aide.
    Jérôme

  2. #2
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 725
    Points : 1 050
    Points
    1 050
    Par défaut
    Bonjour,

    voici quelques idées:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    $qb->select('u,p')
         ->from('User','u')
         ->join('u.profile','p')
         ->groupBy('u')
         ->having('MAX(p.annee)')
          ->where ('p.att1=1');
    ou bien

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $qb->select('u,p')
         ->from('User','u')
         ->join('u.profile','p','ON','p.annee IN (SELECT MAX(p2.annee) FROM Profile p2 GROUP BY p2.user)')
         ->where ('p.att1=1');

  3. #3
    Membre actif
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    546
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 546
    Points : 219
    Points
    219
    Par défaut
    Merci de ta réponse mais ça ne fonctionne pas.
    Dans mon cas il faut faire la jointure sur le id et l'année de la sous requete.
    Or je ne sais pas comment faire ça en DQL...
    Jérôme

  4. #4
    Expert éminent
    Avatar de pmithrandir
    Homme Profil pro
    Responsable d'équipe développement
    Inscrit en
    Mai 2004
    Messages
    2 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable d'équipe développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 418
    Points : 7 295
    Points
    7 295
    Par défaut
    Sans reproduire ta requete, tu peux aussi faire un truc du genre :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT *
    FROM users
    JOIN profile
    ORDER BY user.id, profile.year desc

    Et ton dernier profile sera donc toujours le premier élément de la collection $user->getProfiles().

    Selon le nombre de profile par user, ca peut être valable(tu récupère plus de donnée pour rien, mais ca fonctionnera aussi bien ou presque)

  5. #5
    Membre actif
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    546
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 546
    Points : 219
    Points
    219
    Par défaut
    pmithrandir, je répondrai oui et non
    En effet, ça peut sembler être une solution, sauf que ce n'est pas bon, puisque imaginons que le user ait att1=1 en 2012 et que att1=0 en 2014
    Quand je filtre sur mon attribut att1=1 la ligne va remonter avec la valeur 2012 en année, mais je ne verrai pas la ligne pour l'année 2014
    Et la je peux penser que c'est le dernier profile, erreur !
    A moins que sur chaque user je regarde quel est le dernier profile et que je zappe la ligne si ce n'est pas le dernier...
    bref, moyen...
    Jérôme

  6. #6
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Août 2012
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2012
    Messages : 1
    Points : 1
    Points
    1
    Par défaut
    J'ai exactement le même problème , j ai poste un peu partout.

    Je n'ai aucun probleme a obtenir un resultat avec des performances excellentes en sql natif ( vraiment natif , pas en passant par du natif via doctrine ) et impossible de le faire avec le query builder

  7. #7
    Membre actif
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    546
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 546
    Points : 219
    Points
    219
    Par défaut
    Finalement j'ai résolu mon problème en faisant moi-même ma jointure mais en PHP.
    Donc je fais une requête qui récupère tous mes users et tous leurs profiles qui correspondent à mes critères (att1=1...)
    Ensuite je fais une 2eme requête qui ne prend que le max(année) du profile de chaque user, comme ça j'ai une liste de user avec uniquement l'ID de leur dernier profile.
    Enfin en PHP, je parcours mon 1er tableau résultat et si un profile existe (parcours du 2eme tableau de résultat) je le garde sinon j’enlève la ligne.
    Ce qui fait que je ne garde que les profiles les plus récents.
    Et en mettant le résultat de la 2eme requête en tableau associatif, on n'a même pas besoin de parcourir tout le tableau à chaque fois, donc ça va plus vite.
    Voila !
    Jérôme

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

Discussions similaires

  1. [AC-2010] variable de sous-formulaire dans une requete sans VB
    Par tibjedi dans le forum IHM
    Réponses: 2
    Dernier message: 28/03/2012, 08h45
  2. Réponses: 5
    Dernier message: 12/01/2011, 14h59
  3. [AC-2002] Comment calculer des sous-totaux dans une requete croisee
    Par babinou dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 19/08/2009, 09h43
  4. Table resultant d'une requete sélection dans une jointure
    Par moabomotal dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 14/02/2007, 13h42
  5. [SQL-Server] Sous requete dans une procédure stockée
    Par Worldofdada dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 09/02/2006, 11h18

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