Как использовать более продвинутые параметры в построителе запросов Doctrine 'orderBy()'?

Я пытаюсь использовать естественную сортировку в MySQL через построитель запросов доктрины. Но функция orderBy() не имеет нужных мне параметров.

Это запрос, который мне нужно передать доктрине:

SELECT * FROM `ouvidoria`
ORDER BY CAST(RIGHT(`id`, LENGTH(`id`)-3) AS UNSIGNED) DESC;

я пробовал следующее:

public function getLastKeyOfOrigin($origin) {
    $data = $this->getRepository()->findOneBy(['origin'=>$origin->getId()]);
    $select = $this->em->createQueryBuilder();
    $select->select('o')
           ->from($this->entityPath, 'o')
           ->where("o.origin = :origin")
           ->setParameter('origin', $origin)
           ->orderBy('CAST(RIGHT(o.id, LENGTH(o.id)-3) AS UNSIGNED)', 'DESC')
           ->setMaxResults('1');
     return $select->getQuery()->getOneOrNullResult();
}

который дает следующую ошибку:

Type: Doctrine\ORM\Query\QueryException Message: [Syntax Error] line 0, col 79: Error: Expected known function, got 'CAST'

Стоит ли изучать 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
289
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете сделать это:

$select->select('o')
           ->from($this->entityPath, 'o')
           ->where("o.origin = :origin")
           ->setParameter('origin', $origin)
           ->addSelect('CAST(RIGHT(o.id, LENGTH(o.id)-3) AS UNSIGNED) AS HIDDEN orderCol')
           ->orderBy('orderCol', 'DESC')
           ->setMaxResults('1');

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

спасибо за ответ, но это все еще дает ту же ошибку.

Bruno Souza 24.06.2019 22:22

О, теперь я вижу, проблема была не в сложности выражения, а в использовании функций SQL, которые не переопределяются как функции DQL. Да, в данном случае мой совет просто не имеет отношения к делу. Я думаю, что вам лучше всего использовать собственный запрос, то есть сделать его на простом SQL (doctrine-project.org/projects/doctrine-orm/en/2.6/reference‌​/…). Или вы можете реализовать эти недостающие функции (или создать новую, которая делает то, что вы хотите), но я думаю, что это просто излишество.

alx 24.06.2019 22:26

Жаль, что Doctrine (AFAIK) не позволяет просто вставить фрагмент SQL в QueryBuilder, в отличие, например, от Красноречивый от Laravel. Я предполагаю, что это сломало бы некоторые сильные абстракции в Doctrine.

alx 24.06.2019 22:28

Я, вероятно, в конечном итоге пойду на излишество, перестройка всей системы для использования собственного запроса будет еще хуже. :/

Bruno Souza 24.06.2019 22:29

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

alx 24.06.2019 22:32

А, и обязательный комментарий: кажется, у вас есть два связанных, но разных значения в одном и том же столбце. Это не нормированные данные. Вместо этого у вас должно быть два столбца (возможно, 3, если вам нужно объединить оба значения, но в этом случае виртуальный столбец будет лучше). Но это будет «перестройка всей системы», да.

alx 24.06.2019 22:33
Ответ принят как подходящий

Я решил это, упорядочив запрос по 2 столбцам, но отвечая на заданный вопрос, вы можете использовать класс NativeQuery доктрины для отправки открытого SQL через доктрину.

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