Here's my db schema:
| User | | View |
*-------* *----------*
| id | | id |
| date |
| Movie | | movie_id |
*-------* | user_id |
| id |
| title | | Comment |
| slug | *-----------*
| cover | | id |
| createdAt |
| view_id |
| user_id |
What I'm trying to achieve is to select movies that have at least one view older than any comment posted on a movie for a specific user, or that have never been commented by this user.
I'm using Doctrine 2, and here's what I've done so far:
$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()
;
Problem is that this request throws an exception:
QueryException: [Semantical Error] line 0, col 410 near 'lastCommentedOn': Error: 'lastCommentedOn' does not point to a Class.
and I don't really see why...
Thanks for your enlightenment.
I've ended with this plain SQL solution:
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.