I'd like to select order items from all orders with a specific item. In SQL I'd do it like this:
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
How would I do this query with the query builder?
You can place the Subquery in a number of SQL clauses: WHERE clause, HAVING clause, FROM clause. Subqueries can be used with SELECT, UPDATE, INSERT, DELETE statements along with expression operator.
In MySQL, a subquery is a query within a query. You can create subqueries within your SQL statements. These subqueries can reside in the WHERE clause, the FROM clause, or the SELECT clause.
Subqueries in a HAVING clause HAVING clause is used to filter groups of rows. You may place a subquery in HAVING clause in an outer query. This allows you to filter groups of rows based on the result returned by your subquery.
This is how I would try it:
/** @var Doctrine\ORM\EntityManager $em */ $expr = $em->getExpressionBuilder(); $em->createQueryBuilder() ->select(array('DISTINCT i.id', 'i.name', 'o.name')) ->from('Item', 'i') ->join('i.order', 'o') ->where( $expr->in( 'o.id', $em->createQueryBuilder() ->select('o2.id') ->from('Order', 'o2') ->join('Item', 'i2', \Doctrine\ORM\Query\Expr\Join::WITH, $expr->andX( $expr->eq('i2.order', 'o2'), $expr->eq('i2.id', '?1') ) ) ->getDQL() ) ) ->andWhere($expr->neq('i.id', '?2')) ->orderBy('o.orderdate', 'DESC') ->setParameter(1, 5) ->setParameter(2, 5) ;
I didn't test this of course, and made some assumptions about your models. Possible problems:
Concluding, this may not work first time, but will surely put you on the right track. Do tell us the final 100% correct answer afterwards.
Just to avoid confusion of the last comment posted by clang1234.
The DQL query example really works. It's true that the The expr->in()
will cast the second parameter to an array, in this case the DQL string. What it does, it just create an array with the DQL query string as the first element. That's exactly what the the Expr\Func
is waiting for, an array. It's a little deeper in the Doctrine 2 code that the dql query string array element will be managed correctly. (see DBAL/Platforms/AbstractPlatform.php
method getInExpression
for more details, the array get imploded into IN()
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With