复杂的查询与条令相结合


Complex query join with doctrine

我正在构建一个查询,向用户显示项目,然后显示该项目的最高出价。

示例

詹姆斯的Xbox 360。-出价最高的是55美元。

马里奥的艺术桌出价最高的是25美元。

查询

SELECT i, u
FROM AppBundle:Item i
LEFT JOIN i.user u

我有另一个表出价(一对多关系)。我不知道如何在带有join的同一查询中包含该项目的单个最高出价。

我知道我可以在这个查询之后用函数(关系)运行另一个查询,但出于优化原因,我避免这样做。

解决方案

SQLhttps://stackoverflow.com/a/16538294/75799-但在DQL学说中,这怎么可能呢?

在这种情况下,可以将IN与子查询一起使用
我不确定我是否正确理解了你的模型,但我试图用QueryBuilder进行查询,我相信你会设法用这个例子进行查询:

$qb  = $this->_em->createQueryBuilder();
$sub = $qb;
$sub->select('mbi') // max bid item
    ->where('i.id = mbi.id')
    ->leftJoin('mbi.bids', 'b'))
    ->andWhere($qb->expr()->max('b.value'))
    ->getQuery();
$qb = $qb->select('i', 'u')
         ->where($qb->expr()->in('i', $sub->getDQL()))
         ->leftJoin('i.user', 'u');
$query = $qb->getQuery();
return $query->getResult();

您的SQL查询可能看起来像

select i,u
from i
inner join bids u on i.id = u.item_id
WHERE
    i.value = (select max(value) from bids     where item_id = i.id)
group by i

DQL,我认为不支持子查询,所以您可以尝试使用Having子句,或者看看Doctrine'ORM'Query'Expr是否提供了什么。

为了解决我自己的问题,我在原始实体(项目)中添加了一种方法,以在实体(投标)列表中找到最大实体,使用我在这里写过的Doctrine’s Collections’Criteria

您的Item实体将包含

public function getMaxBid()
{
   $criteria = Criteria::create();
   $criteria->orderBy(['bid.value' => Criteria::ASC]);
   $criteria->setLimit(1);
   return $this->bids->matching($criteria);
}

不幸的是,i不可能通过一个分组查询找到最大出价投标人,但有几种技术可以使逻辑与多个查询一起工作。您可以进行子选择,根据表的大小,这可能会很好地工作。如果你计划发展到无法实现的地步,你可能已经在考虑共享关系数据库,将一些数据转移到事务性较低、性能较高的数据库技术,或者去规范化,但如果你想在纯MySQL中实现这一点,您可以使用一个过程在多个命令中表达如何检查出价并选择性地添加到列表中,还可以在非规范化的高出价表中更新当前的高出价者。这将如何验证投标的复杂逻辑保留在一个管理最严格的地方——数据库中。只需确保您正确使用交易来阻止同时记录2个出价(例如,SELECT FOR UPDATE)。

我曾经请潜在的程序员编写这个查询,看看他们在MySQL方面的经验,许多人认为只进行最大分组就足够了,还有一些人在离开采访时仍然相信它会很好地工作,I是错误的。好问题!