加入并计入DQL

时间:2011-06-13 03:04:04

标签: mysql doctrine doctrine-orm symfony dql

我有一个MySQL命令,我找不到DQL中的等价物。我正在尝试获取列表中评论最多的帖子。这是MySQL命令:

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

结果如下:

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

在DQL中,它应该是:

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

但是这给了:

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

我不明白50来自哪里以及为什么两个结果之间存在差异。你能告诉我如何让这个加入在Doctrine中工作吗?

3 个答案:

答案 0 :(得分:8)

我做了一些测试,发现一切似乎都很好。

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

数据库架构非常简单,我认为不需要任何解释。

#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
            )

    )

如果在Video子句中选择整个v对象而不是其id(v.id而不是SELECT),则查询也会执行。当然,代替id元素,在 th 元素下将有一个Video对象。

在Doctrine 2.1.0-DEV

上测试

答案 1 :(得分:0)

已编辑:人物 - 此答案有效。至少你可以从可能的解决方案中消除这一点。

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

您按post.id分组,而不是post

不过,这是一个总猜测。我不知道DQL,但我知道hibernate,它看起来很相似。如果这是错的,我会删除这个答案 - 请通过评论告诉我。

答案 2 :(得分:-1)

我不知道DQL,这可能是愚蠢的....但你发布了这个:

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

你不应该选择post.id吗?我知道这听起来很奇怪,但据我所知,select post相当于select *。但是,在您的输出中,您只获得了ID列。我认为值得注意(即使不是)。

/准备downvote