Sql 正在做一个。。在条令2中的子查询中
我想从带有特定项目的所有订单中选择订单项目。在SQL中,我会这样做:Sql 正在做一个。。在条令2中的子查询中,sql,database,doctrine-orm,Sql,Database,Doctrine Orm,我想从带有特定项目的所有订单中选择订单项目。在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.o
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 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
methodgetInExpression
了解更多详细信息,数组将内爆为IN()
)谢谢!您的示例中只缺少两件事:名称空间需要在开头使用反斜杠,子查询需要使用getDQL()方法作为字符串提供。我已经编辑了您的示例以更正此问题,谢谢您的更正。对于每个使用Doctrine 2 QueryBuilder的人来说,这将是一个非常有用的参考。最好注意这个解决方案在Doctrine2.0中似乎不起作用。条令\ORM\Query\Expr->in()将第二个参数转换为数组。如果传入DQL,它将不会被解释。如果内部查询有一些绑定参数,这可能是危险的,因为根据我的经验,调用getDql()会使任何此类绑定无效。因此,需要在外部查询中再次将参数与setParameter绑定,否则代码将以“无效参数编号:绑定变量的数量与令牌的数量不匹配”的方式中断。请注意,示例中使用了两个QueryBuilder。这会为下一个家伙节省一些时间。。。