Symfony Query Builder как получить последние сгруппированные записи

У меня есть объект с именем "Местоположение" со следующими полями:

  • id (автоинкремент)
  • транспортное средство (внешний ключ к таблице "транспортное средство")
  • широта
  • lng
  • скорость

Мне нужно получить последние местоположения (с последним идентификатором), сгруппированные по транспортным средствам, с помощью Doctrine Query Builder.

Вот моя функция:

// 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;   
}

Спасибо за помощь.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
1 563
2

Ответы 2

Недавно у меня была похожая проблема. Это можно сделать с помощью подзапроса, чтобы получить информацию о местоположении по максимальному идентификатору местоположения для транспортного средства, а затем присоединить его к выбору внешнего транспортного средства.

К сожалению, это невозможно сделать в DQL, поскольку он не может объединить объект с подзапросом.

Вам нужно будет сделать это в собственном SQL

Что-то вроде

ВЫБРАТЬ * из транспортного средства ЛЕВОЕ СОЕДИНЕНИЕ location ON location.vehicle = vehicle.id ГДЕ location.id в (SELECT MAX (Id) FROM location GROUP BY vehicle)

Сначала вы могли подумать, что это можно сделать в подзапросе DQL, но этот запрос будет работать, только если для каждого транспортного средства есть хотя бы одно местоположение.

Если вы хотите получить данные о транспортном средстве, даже если для этого транспортного средства нет записи о местоположении, вам придется работать над подзапросом, чтобы получить * для него с максимальным идентификатором группы по транспортному средству, а затем присоединиться к основному запросу. Эта часть не поддерживается в DQL.

Чтобы выбрать последнюю запись из объекта местоположения для каждого транспортного средства, вы можете выполнить самостоятельное левое соединение для объекта местоположения с дополнительными критериями соединения, используя предложение WITH, и в проверке предложения where на наличие нулей строки с наивысшим идентификатором для каждого местоположения будут иметь нулевое значение по сравнению с самосоединением ряды.

// 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');            

}

Посмотреть похожие решения

Другие вопросы по теме