在Doctrine 2中执行WHERE .. IN子查询
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Doctrine 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
如何使用查询构建器执行此查询?
答案
我就是这样尝试的:
/** @var DoctrineORMEntityManager $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',
DoctrineORMQueryExprJoin::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)
;
我当然没有对此进行测试,并对您的模型做了一些假设。可能的问题:
- 限制:这在Doctrine 2中有点问题,看起来查询构建器并不是很擅长接受限制。看看here,here和here。
- IN子句通常与数组一起使用,但我认为它将与子查询一起使用。
- 你可能可以使用相同的参数?1,而不是两个参数(因为它们是相同的值),但我不确定。
总而言之,这可能不适用于第一次,但肯定会让你走上正轨。之后告诉我们最终的100%正确答案。
另一答案
只是为了避免混淆clang1234发布的最后评论。
dql查询示例确实有效。确实,expr-> in()会将第二个参数强制转换为数组,在本例中为dql字符串。它做什么,它只是创建一个以dql查询字符串作为第一个元素的数组。这正是Expr Func正在等待的数组。在Doctrine 2代码中更深入一点,dql查询字符串数组元素将被正确管理。 (有关详细信息,请参阅DBAL / Platforms / AbstractPlatform.php方法getInExpression,数组内爆入IN())
以上是关于在Doctrine 2中执行WHERE .. IN子查询的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Doctrine 查询生成器中进行多个 WHERE IN 列查询?
Doctrine2 查询(Builder)在使用“where”和“in”子句后失去关系
Doctrine DQL (Symfony2) - WHERE 连接字段是 IN params