Fare un WHERE .. IN subquery in Doctrine 2

Vorrei selezionare gli articoli dell’ordine da tutti gli ordini con un articolo specifico. In SQL lo farei in questo modo:

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 

Come faccio a fare questa domanda con il generatore di query?

Questo è come lo proverei:

 $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) ; 

Non ho provato questo, naturalmente, e fatto alcune ipotesi sui tuoi modelli. Possibili problemi:

  • Limite: questo è stato un po ‘un problema in Doctrine 2, sembra che Query Builder non sia molto bravo nell’accettare i limiti. Dai un’occhiata qui , qui e qui .
  • La clausola IN viene in genere utilizzata con un array, ma penso che funzionerà con una sottoquery.
  • Probabilmente puoi usare lo stesso parametro? 1, invece di due parametri (perché hanno lo stesso valore), ma non ne sono sicuro.

Concludendo, questo potrebbe non funzionare la prima volta, ma sicuramente ti metterà sulla buona strada. Diteci l’ultima risposta corretta al 100% in seguito.

Giusto per evitare la confusione dell’ultimo commento pubblicato da clang1234.

l’esempio di query dql funziona davvero. È vero che Theprim-> in () invierà il secondo parametro a un array, in questo caso la stringa dql. Quello che fa, crea semplicemente un array con la stringa di query dql come primo elemento. Questo è esattamente ciò che Expr \ Func sta aspettando, un array. È un po ‘più profondo nel codice Doctrine 2 che l’elemento dql query string array verrà gestito correttamente. (vedi il metodo DBAL / Platforms / AbstractPlatform.php getInExpression per maggiori dettagli, l’array viene imploso in IN ())