2011-06-13 5 views
6

J'ai une commande MySQL et je ne trouve pas l'équivalent en DQL. J'essaie d'aller chercher la liste des messages les plus commentés. Voici la commande MySQL:Joindre et compter en DQL

SELECT posts.id, COUNT(comments.id) AS num 
FROM posts 
LEFT JOIN comments ON (posts.id = comments.post_id) 
GROUP BY posts.id 

est le résultat ici:

id num 
1 8 
2 9 
3 17 
4 7 
5 6 
6 20 
7 7 
8 10 
9 14 
10 7 

En DQL, il devrait être:

SELECT post, COUNT(comment.id) AS num 
FROM Entity\Post post 
LEFT JOIN post.comments comment 
GROUP BY post.id 

Mais cela donne:

id num 
1 50 
2 0 
3 0 
4 0 
5 0 
6 0 
7 0 
8 0 
9 0 
10 0 

Je ne comprends pas d'où vient le 50 et pourquoi il y a une différence entre les 2 résultats. Pourriez-vous me dire comment faire fonctionner cette jointure dans Doctrine?

+0

Quelle est la requête exacte générée par la doctrine? Vous pouvez facilement le vérifier en utilisant le WDT de Symfony. De plus, vous devez stocker le nombre total de commentaires dans la table 'Post' et le/décrémenter à chaque fois que vous ajoutez/supprimez un commentaire. – Crozin

+0

Salut Crozin, c'est ce que je suis en train de faire. Mais je veux faire ce travail parce que je veux ajouter une déclaration comme "WHERE post.date>?" Pour obtenir les messages "les plus chauds" pour les dernières 24h, le dernier jour, le mois dernier ...J'exécute ces commandes avec 'doc/console doctrine: query: dql' et' app/console doctrine: query: sql'. – Quentin

Répondre

8

J'ai fait quelques tests et j'ai trouvé que tout semble bien.

Video: id, title, ... 
Comment: id, video_id, content, ... 

Le schéma de la base de données est très simple et je pense qu'il n'y a pas besoin d'explication.

#DQL: 
    SELECT v.id, COUNT(c.id) AS num 
    FROM Video v 
    JOIN v.comments c 
    GROUP BY v.id 
    ORDER BY num DESC 

#Generated SQL: 
    SELECT v0_.id AS id0, COUNT(v1_.id) AS sclr1 
    FROM video v0_ 
    INNER JOIN video_comment v1_ ON v0_.id = v1_.video_id 
    GROUP BY v0_.id 
    ORDER BY sclr1 DESC 

#Result set: 
    Array 
    (
     [0] => Array 
      (
       [id] => 148 
       [num] => 3 
      ) 

     [1] => Array 
      (
       [id] => 96 
       [num] => 2 
      ) 

     [2] => Array 
      (
       [id] => 111 
       [num] => 1 
      ) 

     [3] => Array 
      (
       [id] => 139 
       [num] => 1 
      ) 

    ) 

Si vous sélectionnez tout l'objet Video au lieu de son numéro d'identification (v au lieu de v.id dans SELECT clause) la requête exécutera aussi bien. Bien sûr, au lieu de id élément, il y aura un Video objet sous 0 th élément.

Testé sur Doctrine 2.1.0-DEV

0

EDITED: Les gens - Cette réponse ne pas travail. Au moins, vous pouvez éliminer cela des solutions possibles.

SELECT post, COUNT(comment.id) AS num 
FROM Entity\Post post 
LEFT JOIN post.comments comment 
GROUP BY post 

Vous étiez regroupement par post.id, non post

BTW, ceci est une estimation totale. Je ne connais pas DQL, mais je connais hibernate, et il semble similaire. Si c'est faux, je vais supprimer cette réponse - faites le moi savoir par commentaire.

+0

Salut Bohémien, le regroupement par 'post' ne fait pas mieux. J'ai exactement la même sortie. – Quentin

-1

Je ne sais pas DQL, et cela pourrait être stupide .... mais vous avez posté ceci:

SELECT post, COUNT(comment.id) AS num 
FROM Entity\Post post 
LEFT JOIN post.comments comment 
GROUP BY post.id 

ne devriez-vous la sélection post.id? Je sais que cela semble bizarre, mais d'après ce que je comprends, select post est équivalent à select *. Pourtant, dans votre sortie, vous obtenez seulement la colonne ID. Je pensais que ça valait la peine d'être noté (même si ce n'est pas le cas).

/prépare à downvote