Php 复杂查询连接原则

Php 复杂查询连接原则,php,mysql,symfony,doctrine-orm,left-join,Php,Mysql,Symfony,Doctrine Orm,Left Join,我正在构建一个查询,以向用户显示项目,然后显示项目的最高出价 示例: 詹姆斯的Xbox360最高出价为55美元 马里奥的艺术桌最高出价为25美元 查询 SELECT i, u FROM AppBundle:Item i LEFT JOIN i.user u 我有另一个表出价(一对多关系)。我不确定如何在同一个查询中使用join包含项目的单个最高出价 我知道我可以在这个查询之后使用函数(关系)运行另一个查询,但出于优化的原因,我避免这样做 解决方案 SQL -但是在DQL中这怎么可能呢?您的SQ

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

示例

詹姆斯的Xbox360最高出价为55美元

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

查询

SELECT i, u
FROM AppBundle:Item i
LEFT JOIN i.user u
我有另一个表出价(一对多关系)。我不确定如何在同一个查询中使用join包含项目的单个最高出价

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

解决方案

SQL
-但是在DQL中这怎么可能呢?

您的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
子句,或者查看
doctor\ORM\Query\Expr
是否提供了任何内容

为了解决我自己的问题,我在原始实体(项目)中添加了一个方法,使用我所写的条令集合标准,在实体(投标)列表中查找最大实体

您的
项目
实体将包含

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

   return $this->bids->matching($criteria);
}

您的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
子句,或者查看
doctor\ORM\Query\Expr
是否提供了任何内容

为了解决我自己的问题,我在原始实体(项目)中添加了一个方法,使用我所写的条令集合标准,在实体(投标)列表中查找最大实体

您的
项目
实体将包含

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

   return $this->bids->matching($criteria);
}

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


我曾经要求未来的程序员编写这个查询,看看他们对MySQL的经验有多丰富,很多人认为只需一个max分组就足够了,还有一些人在离开采访时仍然相信它可以很好地工作,而我错了。好问题

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


我曾经要求未来的程序员编写这个查询,看看他们对MySQL的经验有多丰富,很多人认为只需一个max分组就足够了,还有一些人在离开采访时仍然相信它可以很好地工作,而我错了。好问题

在这种情况下,您可以将中的
与子查询一起使用。
我不确定我是否正确理解了您的模型,但我尝试使用
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();

在这种情况下,您可以将中的
与子查询一起使用。
我不确定我是否正确理解了您的模型,但我尝试使用
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示例。但我需要看看这个例子。因为总是有一些不同的方法来做这件事,这不是正常的sql方法。我还不是这方面的专家。@Basit我已经更新了答案,以提供更多细节和代码示例。@Basit包含了条令代码。你也许可以将它升级到存储库级别,我还没有尝试过。谢谢你的帖子,这是一个非常有用和有趣的方法,我不知道。我一定会检查存储库和/或尝试此功能。@Basit不用担心-我遇到了与您几乎相同的事情!感谢您提供SQL示例。但我需要看看这个例子。因为总是有一些不同的方法来做这件事,这不是正常的sql方法。我还不是这方面的专家。@Basit我已经更新了答案,以提供更多细节和代码示例。@Basit包含了条令代码。你也许可以将它升级到存储库级别,我还没有尝试过。谢谢你的帖子,这是一个非常有用和有趣的方法,我不知道。我一定会检查存储库和/或尝试此功能。@Basit不用担心-我遇到了与您几乎相同的事情!作为另一种想法,您可以在最高出价的项目上添加一个额外的外键,并在创建新的最高出价时更新该外键。这将节省您编写子选择的时间