Использование подзапроса MAX () с Doctrine - PullRequest
0 голосов
/ 23 октября 2018

Я пытаюсь преобразовать следующий собственный SQL-запрос в экземпляр построителя запросов для Doctrine 2, но безуспешно.

SELECT r1.*
FROM reservations r1
INNER JOIN (
    SELECT user, max(occurrence) AS max
    FROM reservations
    WHERE team = 'team-id'
    AND canceled = 0
    GROUP BY user
) r2
ON r1.occurrence = r2.max AND r1.user = r2.user
WHERE r1.team = 'team-id'
AND r1.canceled = 0
AND r1.occurrence >= '2018-10-08'
ORDER BY occurrence DESC;

Я пытался создать построитель запросов при использовании INNER JOIN,но это невозможно, потому что он не допускает подзапросов по этому вопросу.Я даже попробовал ->where($qb->expr()->in()), но это не сработало.Так что сейчас у меня немного не хватает возможностей.

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

Может кто-то с опытомработа с Доктриной, пожалуйста, помогите мне?

1 Ответ

0 голосов
/ 24 октября 2018

Doctrine имеет множество досадных ограничений, и вы столкнулись с одним из самых неприятных моментов - отсутствием поддержки подзапросов.

Как говорится, если вы переписываете свой запрос и погружаетесь в источник Doctrine, есть обходной путь - вместо этого создайте самостоятельное объединение.

Необходимо создать экземпляр и добавить свой собственный экземпляр Join в компоновщик, поскольку вряд ли у вас есть необходимые отношения, определенные в вашем Reservationобъект, чтобы иметь возможность использовать определенные отношения для этого.

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

// ReservationRepository.php

use AppBundle\Entity\Reservation;
use Doctrine\ORM\Query\Expr\Join;

return $this->createQueryBuilder('r')
    ->add('join', [
        new Join(Join::LEFT_JOIN, Reservation::class, 'r1', 'WITH', 'r.user = r1.user AND r.team = r1.team AND r1.canceled = :canceled AND r.occurrence < r1.occurrence')
    ], true)
    ->where('r.team = :team')
    ->andWhere('r.canceled = :canceled')
    ->andWhere('r.occurrence >= :occurrence')
    ->andWhere('r1.id IS NULL')
    ->orderBy('r.occurrence', 'DESC')
    ->setParameter('team', $team)
    ->setParameter('canceled', 0)
    ->setParameter('occurrence', '2018-10-08')
    ->getQuery()
    ->getResult();
...