做一个WHERE ..在学说2中的子查询

我想select具有特定项目的所有订单中的订单项目。 在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 

我将如何做查询生成器这个查询?

这是我将如何尝试它:

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

我当然没有testing这个,并且对你的模型做了一些假设。 可能的问题:

  • 限制:这在教义2中有些问题,似乎查询生成器不是很好的接受限制。 看看这里 , 在这里和这里 。
  • IN子句通常与一个数组一起使用,但是我认为它可以和子查询一起工作。
  • 你可能可以使用相同的参数?1,而不是两个参数(因为它们是相同的值),但我不知道。

总结一下,这可能不是第一次,但肯定会把你放在正确的轨道上。 事后告诉我们最后的100%正确的答案。

只是为了避免混淆clang1234发布的最后一条评论。

这个dql查询例子确实有效。 确实,expr-> in()会将第二个参数强制转换为一个数组,在本例中是dqlstring。 它做什么,它只是创build一个与dql查询string作为第一个元素的数组。 这正是Expr \ Func正在等待的一个数组。 在Doctrine 2代码中,dql查询string数组元素将得到正确pipe理。 (有关更多详细信息,请参阅DBAL / Platforms / AbstractPlatform.php方法getInExpression,数组被解压缩成IN())