Symfony Query Builder如何获取最后分组的记录

时间:2018-07-10 16:16:39

标签: php sql symfony doctrine greatest-n-per-group

我有一个名为“ Location”的实体,其中包含以下字段:

  • id(自动递增)
  • 车辆(“车辆”表的外键)
  • lat
  • lng
  • 速度

我需要使用学问查询生成器获取按车辆分组的最后位置(具有最后一个ID)。

这是我的功能:

// Find locations
public function findLocations($idFleet, $select, $from, $to)
{
    $qb = $this->createQueryBuilder('l')
    ->innerJoin('l.vehicle', 'v')
    ->where('v.fleet = :fleet')
    ->setParameter('fleet', $idFleet)
    ->andWhere('v.gps = :gps')
    ->setParameter('gps', true);

    // Last locations
    if ( $select == "last"){
        $qb->groupBy('l.vehicle')
            ->orderBy('l.id', 'ASC');            
    }
    // else Interval locations
    else if ( $select == "interval"){
        if( $from != ""){
            $from = (new \DateTime())->setTimestamp($from);
            $qb->andWhere('l.time >= :from')
            ->setParameter('from', $from);
        }
        if( $to != ""){
            $to = (new \DateTime())->setTimestamp($to);
            $qb->andWhere('l.time <= :to')
            ->setParameter('to', $to);
        }
    }
    $locations = $qb->getQuery()->getResult();
    return $locations;   
}

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

要从位置实体中为每辆车选择最新记录,您可以使用WITH子句在位置实体上执行带有附加联接条件的自左联接,并在where子句中检查空值,即每个位置ID最高的行对于自连接行,将为null。

// Last locations
if ( $select == "last"){
    $qb
    ->leftJoin( 'YourBundle\Entity\Location', 'l1', 'WITH', 'l.vehicle = l1.vehicle AND l.id < l1.id' )
    ->andWhere('l1.vehicle IS NULL' )
    ->orderBy('l.id', 'ASC');            

}

查看类似的解决方案

答案 1 :(得分:0)

我最近有一个类似的问题。 可以使用子查询通过车辆的最大位置ID获取位置信息,然后将其左联接到外部车辆选择中。

不幸的是,这无法在DQL中完成,因为它无法通过子查询将实体联接在一起。

您将必须在本机SQL中完成

类似

从车辆的左联接位置中选择* location.vehicle = vehicle.id WHERE location.id(从位置GROUP BY车辆中选择MAX(Id))

您可能一开始会以为可以在DQL子查询中执行此操作,但是只有每辆车至少有一个位置时,此查询才有效。

如果即使没有该车辆的位置条目,仍要获取车辆数据,则必须对子查询进行操作,以获取*具有最大id按车辆分组的*,然后将其与主要查询。这是DQL不支持的部分