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 et SUBQUERIES


Sujet :

ORM PHP

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 24
    Par défaut Doctrine et SUBQUERIES
    Bonjour,

    Je tourne en rond sur un problème de sous requête et n'arrive pas trouver de solution qui fonctionne, voici le sujet

    J'ai une table d'Articles (blog) et une table de Commentaires associés à ces Articles, je souhaite sortir une liste des Articles triée par l'id (ou le pseudo) du dernier user ayant fait un commentaire :

    Article2 carla
    Article12 carla
    Article5 nicolas
    Article7 nicolas
    Article10 nicolas

    Mes tables

    Articles { id, titre ...}
    Commentaires { id, id_article, id_user ...}

    Je souhaite faire un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $q->from('Articles a')
       ->leftJoin('a.Commentaires c')
       ->where('c.id = ( select max(c2.id) from Commentaires c2 where c2.id_article = a.id group by c2.id_article )' )
       ->orderBy('c.id_user')
    Le champ Commentaires.id étant autoincrement un max devrait suffire a trouver le plus récent.

    le résultat retourné n'est pas le bon, en fait rien n'est retourné car Doctrine modifie complètement la sous requête et ne conserve pas mon alias c2 et le transforme en alias c

    J'ai essayé avec $q2 = $q->createSubquery( ... ) mais je n'arrive pas non plus à m'en sortir


    http://www.symfony-project.org/cookb..._with_doctrine


    Qqu'un aurait-il déjà utilisé ce genre de chose qui sommes toutes est plutôt simple normalement :


    Tnx

  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
    A vue de nez et rapidement dit, je remplacerais, dans ton where le = par un IN.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 24
    Par défaut
    Bonjour Michel,

    J'ai déjà essayé cette solution mais ça ne marche pas non plus, en fait avec plus de traces voilà le message que j'ai

    500 | Internal Server Error | Doctrine_Exception
    Couldn't find class c2

    Et si j'enlève l'alias de la sous requête comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select max(id) from Commentaires where id_article = a.id group by id_article
    Alors j'ai un message qui dit 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'mabdd.Commentaires' doesn't exist'

    C'est comme si l'alias contenu dans le schema.yml n'était pas reconnu (pourtant c'est bien le bon) et que donc l'alias n'était pas remplacé par le nom de la table.

    Je n'ai pas l'impression que ma requête soit bien compliquée pourtant !

    Any (other) idea ?

  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
    Là tu es en SQL direct, pas en doctrine (pour le select inclu). Tu dois mettre le nom de la table, pas le nom de l'objet dans doctrine.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 24
    Par défaut
    Michel,

    Je viens d'essayer en mettant le nom de la table avec le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $q->from('Articles a')
       ->leftJoin('a.Commentaires c')
       ->where('c.id = ( select max(c2.id) from blog_commentaires c2 where c2.id_article = a.id group by c2.id_article )' )
       ->orderBy('c.id_user')
    Mais dans ce cas j'obtiens une erreur 'Couldn't find class c2'

    Et si j'enlève l'alias c2 alors le SQL généré pour la subquery est le suivant, donc rien n'est retourné et lorsque je prend la requête générée et la met sous mysql j'obtiens un message d'erreur indiquant que c.id n'existe pas (le c.id de la subquery), je pense donc que le parser de Doctrine réaffecte les alias qu'on lui donne mais ne le reporte pas dans la subquery.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select MAX(c.id) from blog_commentaires where id_article = c.id group by id_article
    Dans ce genre de cas je me demande toujours si il n'y a pas un truc hyper simple que je ne vois pas !

  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
    En mode debug, dans la barre de débug tu as les requêtes envoyées, il pourrait être intéressant de voir ce que doctrine fait de ta requête.

    Essaye avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $q->from('Articles a')
       ->leftJoin('a.Commentaires c')
       ->where('c.id = ( select max(d.id) from blog_commentaires d where d.id_article = a.id group by d.id_article )' )
       ->orderBy('c.id_user')

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 24
    Par défaut
    Je viens d'essayer le code que tu as donné, on remplace l'alias c2 par l'alias d

    L'erreur suivante est remontée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    500 | Internal Server Error | Doctrine_Exception
    Couldn't find class d
    J'ai bien l'impression que le parser ne transforme pas l'alias présent dans la subquery par l'alias qu'il a généré dans la query principale, et c'est ce que je vois à l'écran (rien dans le log à cause du plantage je pense)

    Je viens d'essayer avec un createSubquery() et c'est la même chose car il faut faire référence à l'alias d'une table située dans une query externe et le parser ne semble pas réaffecter l'alias.

    Sais tu si il existe une fonction similaire à getRootAlias mais qui permettrait de connaitre l'alias d'une table référencée dans une requête ? (pas trouvé pour l'instant dans la doc en ligne)

  8. #8
    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
    Non.

    Dans la doc de doctrine, il y a une requête similaire, mais l'allias était sur 1 caractère. Et les allias sont toujours sur un caractère dans tous les exemples et j'ai pris l'habitude de n'utiliser que des alias sur 1 caractères. Cela valait le coup d'essayer.

    Ce qui est bizarre, c'est que c'est sensé marcher.

    Peux-tu poster ton schema et tes fixtures ?

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 24
    Par défaut
    J'utilise un pager Doctrine et je me demande si ce n'est pas la source de mes problèmes, bien qu'encore une fois la requête générée avant le passage au Pager soit fausse.

    Devant poursuivre sur mon projet et par manque de temps j'ai finalement procédé autrement en dupliquant un peu de code sql et finalement, même si je n'ai pas le résultat que j'attendais cela me convient pour l'instant (liste des Articles ayant au moins un Commentaire, pour chaque Article une fonction qui remonte le User ayant fait le dernier commentaire ...)

    Je pense que je reviendrai dessus plus tard,

    En tout cas Merci pour ton aide.

Discussions similaires

  1. Réponses: 11
    Dernier message: 10/11/2006, 11h28
  2. check constraint et subquery
    Par mauroyb0 dans le forum Oracle
    Réponses: 3
    Dernier message: 31/10/2006, 15h54
  3. Subquery returns more than 1 row
    Par Mathelec dans le forum Requêtes
    Réponses: 12
    Dernier message: 03/08/2006, 14h25
  4. [insert][select] Subqueries not allowed
    Par Invité dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 05/09/2005, 11h56
  5. [CR-subquery] faire un count...
    Par d@rthwing dans le forum SAP Crystal Reports
    Réponses: 3
    Dernier message: 29/06/2005, 16h36

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