2015-07-21 2 views
2

Я не могу преобразовать этот запрос:Невозможно преобразовать MySql запрос с использованием доктрины DQL или QueryBuilder

SELECT c.title, COUNT(*), 
(
    SELECT ba_thumb.link 
    FROM ba_video 
    INNER JOIN video_channel ON video_channel.video_id=ba_video.id 
    INNER JOIN ba_thumb ON ba_thumb.video_id=video_channel.video_id 
    INNER JOIN ba_channel ON ba_channel.id=video_channel.channel_id 
    WHERE video_channel.channel_id=c.id 
    ORDER BY ba_video.views DESC, ba_thumb.id ASC 
    LIMIT 1 
) AS ba_thumb_link 
FROM ba_channel c 
INNER JOIN video_channel ON video_channel.channel_id=c.id 
INNER JOIN ba_video ON ba_video.id=video_channel.video_id 
GROUP BY video_channel.channel_id 
ORDER BY COUNT(*) DESC 

в DQL или с помощью QueryBuilder.

Я пытался в DQL:

return $this->_em->createQuery(' 
      SELECT c.title, COUNT(*), 
      (
       SELECT t.link 
       FROM BAVideoGalleryBundle:Video v 
       INNER JOIN v.channels c 
       INNER JOIN v.thumbs t 
       WHERE c.id=mc.id 
       ORDER BY v.views DESC, t.id ASC 
       LIMIT 1 
      ) 
      FROM BAVideoGalleryBundle:Channel mc 
      INNER JOIN BAVideoGalleryBundle:Video mv 
      GROUP BY mv.Channels.id 
      ORDER BY COUNT(*) DESC') 
      ->getResult(); 

я получаю:

"[Syntax Error] line 0, col 216: Error: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got 'LIMIT' "

И я попытался с помощью QueryBuilder:

$query = $this->getEntityManager()->createQueryBuilder() 
    ->select('c.title, COUNT(*)') 
    ->from('BAVideoGalleryBundle:Channel', 'mc') 
    ->innerJoin('BAVideoGalleryBundle:Video', 'mv') 
    ->groupBy('mv.Channels.id') 
    ->orderBy('COUNT(*)', 'DESC'); 

$subquery = $this->getEntityManager()->createQueryBuilder() 
    ->select('t.link') 
    ->from('BAVideoGalleryBundle:Video', 'v') 
    ->innerJoin('v.channels', 'c') 
    ->innerJoin('v.thumbs', 't') 
    ->where('c.id=mc.id') 
    ->orderBy('v.views', 'DESC') 
    ->orderBy('t.id', 'ASC') 
    ->getQuery() 
    ->getResult(); 

return $query->addSelect('('.$subquery->getDql().')') 

Но корреляция не работает, я получаю:

[Semantical Error] line 0, col 105 near 'mc.id ORDER BY': Error: 'mc' is not defined

+0

Проверьте свое 'dev.log' в вашем приложении/журналах. Или проверьте свой общий журнал запросов MySQL, чтобы узнать, что ваш фактический запрос получает от доктрины. –

+1

LIMIT не существует в DQL, вы должны использовать '-> setMaxResults (1)' –

+0

и использовать setFirstResult (с setMaxResults). Затем, чтобы сделать Limit 0,10, вы получите в конце вашего запроса .....-> orderBy ('t.id', 'ASC') -> setFirstResult (0) -> setMaxResults (1) – Nico

ответ

1

Это одна из тех ситуаций, когда Doctrine ORM, скорее всего, вызовет у вас больше проблем, чем решает. Вы можете:

  1. Используйте native query и соответствующие ResultSetMapping установки
  2. реорганизовать SQL запрос в то, что доктрина может работать в DQL. Глядя на запрос, который у вас есть, есть несколько способов, которыми вы могли бы это сделать (например, обрабатывать подзапрос как временную таблицу в части FROM/JOIN), но я не вижу способа, которым Doctrine DQL позволял бы
  3. Просто пойдите для прямого SQL, используя Doctrine DBAL. Похоже, вы используете $this->_em, что заставляет меня думать, что вы в EntityRepository, так что вы могли бы сделать: $this->_em->getConnection(), чтобы получить DBAL connection, а затем просто сделать $conn->query(). Очевидно, что таким образом вы теряете преимущества ORM (агностик базы данных и т. Д.), Но вы можете думать о ORM как о том, что у вас есть сложный запрос на выполнение налоговых операций.

Я понимаю, что ничто из этого не является идеальным, но из-за опыта, иногда лучше удалять Doctrine ORM с пути, чтобы достичь того, что вам нужно.

+0

Чаще всего чем нет, выполнение нескольких простых запросов выполняется быстрее, чем один большой запрос с несколькими объединениями и подвыборкой. Поэтому я согласен с предложениями @ john-noel. –

Смежные вопросы