subquery doctrine 2

166
01 мая 2019, 02:50

Есть запрос

SELECT * FROM vocabulary.word
    WHERE movie_id = (select movie_id from vocabulary.word order by id desc LIMIT 1)
    AND season = (select season from vocabulary.word order by id desc LIMIT 1)
    AND episode = (select episode from vocabulary.word order by id desc LIMIT 1)  

не могу переписать на подзапрос в доктрине так не работает

       $query = $this->createQueryBuilder('w1')
        ->select([
            'w1.movie',
            'w1.season',
            'w1.episode'
        ])
        ->orderBy('w1.id', 'DESC')
        ->setMaxResults(1)
    ;
    return $this->createQueryBuilder('w')
        ->select([
            'w.name as word',
            'w.translation as translation',
            'm.name as movie',
            'w.season as season',
            'w.episode as episode',
        ])
        ->leftJoin('w.movie', 'm')
        ->where($query->expr()->eq('m.movie', $query->getDQL()))
        ->andWhere($query->expr()->eq('w.season', $query->getDQL()))
        ->where($query->expr()->eq('w.episode', $query->getDQL()))
        ->orderBy('RAND()')
        ->setMaxResults($limit)
        ->getQuery()
        ->getResult();

[Syntax Error] line 0, col 172: Error: Expected Literal, got 'SELECT' вот такая ошибка вылетает с чем это может быть связано?

Answer 1

Чтобы в проверке использовать подзапросы, необходимо, чтобы подзапрос возвращал одно поле. А у вас подзапрос возвращает 3. В вашем случае придется сделать 3 разных подзапроса для movie,season,episode.

Или вообще не связываться с подзапросами, а выполнить один запрос, а во второй подставить конкретные значения movie,season,episode

Если для подзапроса используется проверка eq, то DQL подзапроса надо внести в скобки '('.$movieQuery->getDQL().')'

$movieQuery = $this->createQueryBuilder('w1')
    ->select('w1.movie')
    ->orderBy('w1.id', 'DESC')
    ->setMaxResults(1)
    ->getQuery();
$seasonQuery = $this->createQueryBuilder('w1')
    ->select('w1.season')
    ->orderBy('w1.id', 'DESC')
    ->setMaxResults(1)
    ->getQuery();
$episodeQuery = $this->createQueryBuilder('w1')
    ->select('w1.episode')
    ->orderBy('w1.id', 'DESC')
    ->setMaxResults(1)
    ->getQuery();
return $this->createQueryBuilder('w')
    ->select([
        'w.name as word',
        'w.translation as translation',
        'm.name as movie',
        'w.season as season',
        'w.episode as episode',
    ])
    ->leftJoin('w.movie', 'm')
    ->where($query->expr()->eq('m.movie', '('.$movieQuery->getDQL().')'))
    ->andWhere($query->expr()->eq('w.season', '('.$seasonQuery->getDQL().')'))
    ->where($query->expr()->eq('w.episode', '('.$episodeQuery->getDQL().')'))
    ->orderBy('RAND()')
    ->setMaxResults($limit)
    ->getQuery()
    ->getResult();
Answer 2

Попробуйте переписать запрос на

SELECT w.* 
FROM vocabulary.word w,
     ( select movie_id 
       from vocabulary.word  
       order by id desc LIMIT 1) sq1,
     ( select season  
       from vocabulary.word  
       order by id desc LIMIT 1) sq2,
     ( select episode  
       from vocabulary.word  
       order by id desc LIMIT 1) sq3
WHERE w.movie_id = sq1.movie_id 
  AND w.season = sq2.season 
  AND w.episode = sq3.episode 

Возможно, в такой форме будет проще.

READ ALSO
Неоднозначный вызов функции класса

Неоднозначный вызов функции класса

Почему компилятор пишет

168
Одинаковы ли типы const int и int в шаблонах?

Одинаковы ли типы const int и int в шаблонах?

Почему программа выводит 00, ведь const int = int, то есть вызов идёт к одной и той же функции, а значит статическая переменная увеличится на единицу...

131
Передача лямбды шаблонной функции

Передача лямбды шаблонной функции

Как передать в шаблон с параметром-функцией лямбду? Почему так не работает?

195