Doctrine Query Language получает максимальный / последний ряд на группу

Я пытаюсь и не могу перевести мой относительно простой оператор SQL в тот, который будет работать в рамках Doctrine.

Это оператор SQL, который работает так, как требуется при запуске с моей базой данных:

SELECT a.*
FROM score a
INNER JOIN (
SELECT name, MAX(score) AS highest
FROM score
GROUP BY name
) b
ON a.score = b.highest AND a.name = b.name
GROUP BY name
ORDER BY b.highest DESC, a.dateCreated DESC

Вот попытка DQL до сих пор:

$kb = $em->createQuery(
"SELECT a
FROM ShmupBundle:Score a
INNER JOIN a.name ShmupBundle:Score b WITH a.score = b.score AND a.name = b.name GROUP BY b.name
WHERE a.platform='keyboard'
GROUP BY a.name
ORDER BY b.score DESC, a.dateCreated DESC");

Который в настоящее время дает эту ошибку:

[Semantical Error] line 0, col 73 near 'ShmupBundle:Score': Error: Class ShmupBundle\Entity\Score has no association named name

Сама таблица довольно проста:
идентификатор, имя, оценка, платформа, дата создания

Есть несколько записей с одним и тем же именем, но разные оценки. Я хочу показать только «высокий балл» по имени. Я пробовал и выключал в течение дня или два без удачи. Может кто-то указать мне верное направление?

2

Решение

Запрос, который вы пытаетесь сделать с доктриной, связан с . Чтобы использовать подзапрос, а затем присоединиться к основному запросу, усложняйте работу с доктриной. Ниже приведена переписанная версия SQL для получения тех же результатов без использования каких-либо агрегатных функций:

SELECT
a.*
FROM
score a
LEFT JOIN score b
ON a.name = b.name
AND a.score < b.score
WHERE b.score IS NULL
ORDER BY a.score DESC

DEMO

Чтобы преобразовать вышеупомянутый запрос, эквивалентный доктрине или DQL, легко, ниже приведена версия DQL вышеупомянутого SQL:

SELECT a
FROM AppBundle\Entity\Score a
LEFT JOIN AppBundle\Entity\Score b
WITH a.name = b.name
AND a.score < b.score
WHERE b.score IS NULL
ORDER BY a.score DESC

Или с помощью построителя запросов вы можете написать что-то вроде того, что я тестировал ниже с помощью Symfony 2.8, используя ДЕМО Схема

$DM   = $this->get( 'Doctrine' )->getManager();
$repo = $DM->getRepository( 'AppBundle\Entity\Score' );
$results = $repo->createQueryBuilder( 'a' )
->select( 'a' )
->leftJoin(
'AppBundle\Entity\Score',
'b',
'WITH',
'a.name = b.name AND a.score < b.score'
)
->where( 'b.score IS NULL' )
->orderBy( 'a.score','DESC' )
->getQuery()
->getResult();

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

7

Другие решения

Внутреннему оператору соединения нужен первый аргумент в виде таблицы, что является семантической ошибкой в ​​вашем запросе.

$kb = $em->createQuery(
"SELECT a
FROM ShmupBundle:Score a
INNER JOIN ShmupBundle:Score b ON a.score = b.score AND a.name = b.name GROUP BY b.name
WHERE a.platform='keyboard'
GROUP BY a.name
ORDER BY b.score DESC, a.dateCreated DESC");
2

использовать этот
в классе

 $name = $em->getRepository('AppBundle:BlogPost')->getMaxId();

в репозитории вы можете использовать что-то вроде

 public function getMaxId()
{
$qb = $this->createQueryBuilder('u');
$qb->select('u, MAX(id) as idMax');
return $qb->getQuery()->getSingleResult();
}
1

  • MySQL не понимает : синтаксис. Если ShmupBundle:Score предполагается, что база данных и таблица, а затем использовать ., Если Доктрина должна заменить это чем-то, то что она делает с этим?
  • Там может быть только один GROUP BY пункт, и это должно быть после WHERE пункт. Попробуйте удалить GROUP BY b.name,
  • Там нет необходимости GROUP BY и то и другое b.name а также a.name так как они равны.
0
По вопросам рекламы [email protected]