Подтвердить что ты не робот

Выполнение WHERE.. В подзапросе в Doctrine 2

Я хотел бы выбрать элементы заказа из всех заказов с определенным элементом. В SQL я бы сделал это следующим образом:

SELECT DISTINCT i.id, i.name, order.name 
FROM items i 
JOIN orders o ON i.order_id=o.id 
WHERE o.id IN (
   SELECT o2.id FROM orders o2
   JOIN items i2 ON i2.order_id=o2.id AND i2.id=5
)
AND i.id != 5
ORDER BY o.orderdate DESC
LIMIT 10

Как мне выполнить этот запрос с построителем запросов?

4b9b3361

Ответ 1

Вот как я попробую:

$qb->select(array('DISTINCT i.id', 'i.name', 'o.name'))
   ->from('Item', 'i')
   ->join('i.order', 'o')
   ->where(
       $qb->expr()->in(
           'o.id',
           $qb2->select('o2.id')
               ->from('Order', 'o2')
               ->join('Item', 
                      'i2', 
                      \Doctrine\ORM\Query\Expr\Join::WITH, 
                      $qb2->expr()->andX(
                          $qb2->expr()->eq('i2.order', 'o2'),
                          $qb2->expr()->eq('i2.id', '?1')
                      )
               )
               ->getDQL()
       )
   )
   ->andWhere($qb->expr()->neq('i.id', '?2'))
   ->orderBy('o.orderdate', 'DESC')
   ->setParameter(1, 5)
   ->setParameter(2, 5)
   ;

Я не проверял это, конечно, и сделал некоторые предположения о ваших моделях. Возможные проблемы:

  • Предел: это была некоторая проблема в Doctrine 2, кажется, что построитель запросов не очень хорош в принятии ограничений. Посмотрите здесь, здесь и здесь.
  • Предложение IN обычно используется с массивом, но я думаю, что он будет работать с подзапросом.
  • Вероятно, вы можете использовать один и тот же параметр? 1 вместо двух параметров (потому что они одного и того же значения), но я не уверен.

В заключение, это может не сработать в первый раз, но, несомненно, приведет вас к правильному пути. После этого сообщите нам окончательный 100% правильный ответ.

Ответ 2

Просто чтобы избежать путаницы последнего комментария, опубликованного clang1234.

пример запроса dql действительно работает. Верно, что выражение expr- > in() передаст второй параметр в массив, в этом случае строку dql. Что он делает, он просто создает массив с строкой запроса dql в качестве первого элемента. Это то, что ждет Expr\Func, массив. Это немного глубже в коде Doctrine 2, что элемент массива элементов запроса dql будет правильно управляться. (см. DBAL/Platforms/AbstractPlatform.php метод getInExpression для получения более подробной информации, массив вставляется в IN())