这是我的数据库架构:
| 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.
我真的不明白为什么......
感谢您的启发。
答案 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