У меня есть таблица событий с заголовком и описанием события, и у меня есть таблица eventInstance, где хранятся даты и места проведения события. Так что это отношение один к n: у одного события может быть много экземпляров.
Сейчас я пытаюсь выбрать только самый последний экземпляр события. В SQL запрос выглядит так:
select e.id, e.title, ei.start_date
from event e
LEFT join event_instance ei on ei.id =
(SELECT id FROM event_instance ei where ei.event_id = e.id ORDER BY start_date asc, start_time asc LIMIT 1)
ORDER BY start_date asc, start_time asc LIMIT 20;
Я пытаюсь переписать команду sql в dql. Пока у меня есть это:
SELECT e, ei
FROM AppBundle:Event e LEFT JOIN e.eventInstances ei WITH ei =
(SELECT a FROM AppBundle:EventInstance a WHERE a.event = e ORDER BY a.startDate asc, a.startTime asc)
Моя проблема в том, что в dql нет команды LIMIT, поэтому я не могу ограничить подзапрос, чтобы получить один результат. Итак, ошибка, которую я получаю при выполнении этого запроса:
SQLSTATE[21000]: Cardinality violation: 7 ERROR: more than one row returned by a subquery used as an expression
Есть ли способ, которым я могу сделать эту работу?
Создайте подзапрос, затем установите максимальное количество результатов для этого.
$subDql = 'SELECT a
FROM AppBundle:EventInstance a
WHERE a.event = e
ORDER BY a.startDate asc, a.startTime asc';
$subQuery = $this->getEntityManager()
->createQuery($subDql)
->setMaxResults(1)
;
$dql = 'SELECT e, ei FROM AppBundle:Event e
LEFT JOIN e.eventInstances ei
WITH ei = (' .$subQuery . ')'
;
$query = $this->getEntityManager()
->createQuery($dql)
->setMaxResults($yourOtherLimit)
;
$resultCollection = $query->getResult();
Эквивалент DQL для вашего решения (чтобы получить последний ряд на группу) будет что-то вроде
SELECT e,a
FROM AppBundle:Event e
JOIN e.eventInstances a
LEFT JOIN AppBundle\Entity\Score b
WITH a.event = b.event
AND a.startDate < b.startDate
AND a.startTime < b.startTime
WHERE b.event IS NULL
ORDER BY a.startTime DESC
ИЛИ ЖЕ
SELECT e,a
FROM AppBundle:Event e
JOIN e.eventInstances a
LEFT JOIN AppBundle\Entity\Score b
WITH a.event = b.event
AND a.startDate = b.startDate
AND a.startTime < b.startTime
WHERE b.event IS NULL
ORDER BY a.startTime DESC