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

Posted

技术标签:

【中文标题】Symfony Query Builder 如何获取最后分组的记录【英文标题】:Symfony Query Builder how to get last grouped records 【发布时间】:2018-12-18 13:58:09 【问题描述】:

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

id(自动递增) 车辆(“车辆”表的外键) 纬度 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;   

感谢您的帮助。

【问题讨论】:

【参考方案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');            


查看类似的解决方案

Doctrine Query Language get Max/Latest Row Per Group

doctrine dbal get latest chat message per group

DQL Doctrine query translation

Doctrine DQL greatest-n-per-group

【讨论】:

【参考方案2】:

我最近遇到了类似的问题。 这可以使用子查询来完成,通过车辆的最大位置 ID 获取位置信息,然后将其连接到外部车辆选择。

很遗憾,这不能在 DQL 中完成,因为它无法将实体与子查询连接起来。

您必须在本机 SQL 中执行此操作

类似

SELECT * from vehicle LEFT JOIN location ON location.vehicle = vehicle.id WHERE location.id in (SELECT MAX(Id) FROM location GROUP BY vehicle)

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

如果即使没有该车辆的位置条目,您仍想获取车辆数据,您将必须处理子查询以获取 * 因为它具有按车辆的最大 ID 组,然后将其加入主要查询。这是DQL不支持的部分

【讨论】:

以上是关于Symfony Query Builder 如何获取最后分组的记录的主要内容,如果未能解决你的问题,请参考以下文章

Symfony Query Builder join ON 和 WITH 区别

Symfony 表单 query_buider 和实体存储库

如何使用 spatie/laravel-query-builder 过滤/搜索具有关系的数据? (拉拉维尔)

Symfony 表单只读字段

如何使用 laravel Query Builder 进行复杂查询

Symfony2,如何使表单标签类/属性与​​其输入不同?