如何在DQL条件下使用MAX函数?

时间:2015-02-05 17:50:39

标签: php doctrine dql

这是我的数据库架构:

| User  |      | View     |
*-------*      *----------*
| id    |      | id       |
               | date     |
| Movie |      | movie_id |
*-------*      | user_id  |
| id    |
| title |      | Comment   |
| slug  |      *-----------*
| cover |      | id        |
               | createdAt |
               | view_id   |
               | user_id   |

我想要实现的目标是选择至少有一个视图比电影上为特定用户发布的任何评论旧的电影,或者该用户从未评论过的电影。

我正在使用Doctrine 2,这是我到目前为止所做的:

$this->createQueryBuilder('movie')
    ->select('DISTINCT movie.id', 'movie.title', 'movie.slug', 'movie.cover')
    ->addSelect('MAX(view.date) as lastViewedOn')
    ->addSelect('MAX(comment.createdAt) as lastCommentedOn')
    ->innerJoin('movie.views', 'view', 'WITH', 'view.user = :user')
    ->leftJoin('movie.comments', 'comment', 'WITH', 'comment.author = :user')
    ->andWhere(
        $qb->expr()->orX('lastCommentedOn IS NULL', 'lastViewedOn > lastCommentedOn')
    )
    ->orderBy('lastViewedOn', 'DESC')
    ->setParameter('user', $user)
    ->getQuery()
    ->getScalarResult()
;

问题是此请求引发异常:

QueryException: [Semantical Error] line 0, col 410 near 'lastCommentedOn': Error: 'lastCommentedOn' does not point to a Class.

我真的不明白为什么......

感谢您的启发。

1 个答案:

答案 0 :(得分:0)

我已经用这个简单的SQL解决方案结束了:

        SELECT m.id, m.title, m.slug, m.cover, v.maxDate
            FROM movie m
            INNER JOIN (
                SELECT movie_id, MAX(date) maxDate
                FROM view
                WHERE user_id = :user
                GROUP BY movie_id
            ) v ON m.id = v.movie_id
            LEFT JOIN (
                SELECT id, movie_id, MAX(created_at) maxDate
                FROM comment
                WHERE author_id = :user
                GROUP BY movie_id
            ) c ON c.movie_id = m.id
        WHERE m.online_on <= :from AND (m.offline_on IS NULL OR m.offline_on > :from)
        AND (c.id IS NULL OR v.maxDate > c.maxDate)
        ORDER BY v.maxDate DESC