在原则2中执行 WHERE. . IN 子查询

我想从所有订单中选择带有特定项目的订单项,在 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

如何使用查询生成器执行此查询?

110023 次浏览

我会这样试试:

/** @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)
;

当然,我没有测试这个,而是对你的模型做了一些假设。可能的问题:

  • 限制: 这在原则2中是个问题,似乎查询构建器不太善于接受限制。一定要看看 给你给你给你
  • IN 子句通常与数组一起使用,但我认为它可以与子查询一起使用。
  • 你可以使用相同的参数吗?1,而不是两个参数(因为它们是相同的值) ,但我不确定。

总而言之,这可能不是第一次起作用,但肯定会让你走上正确的道路。一定要事后告诉我们最后100% 正确的答案。

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

DQL 查询示例确实有效。的确,expr->in()将第二个参数强制转换为数组,在本例中为 DQL 字符串。它所做的只是创建一个以 DQL 查询字符串作为第一个元素的数组。这正是 Expr\Func所等待的,一个数组。在 Doctrine 2代码中,dql 查询字符串数组元素将被正确管理,这一点稍微深入一些。(参见 DBAL/Platforms/AbstractPlatform.php方法 getInExpression了解更多细节,数组内爆到 IN())