Доктрина 2 СЛУЧАЙ DQL При подсчете

#mysql #symfony #doctrine-orm #dql

#mysql #symfony #doctrine-orm #dql

Вопрос:

У меня есть этот запрос в собственном коде MySQL

 SELECT *
FROM `turn`
LEFT JOIN (
    poi
) ON ( turn.id = poi.turn_id )
GROUP BY turn.id
ORDER BY count( case when poi.image = 1 then 1 else null end) DESC;
  

Мне нужно перестроить это в Doctrine 2 DQL

Моя попытка до сих пор заключается в следующем:

 SELECT t, COUNT((CASE WHEN BundleEntityPoi p.image = 1 then 1 ELSE NULL END)) AS num
FROM BundleEntityTurn t
JOIN t.pois p
GROUP BY t.id
ORDER BY num DESC
  

И я получаю эту ошибку:

An exception has been thrown during the rendering of a template ("[Syntax Error] line 0, col 99: Error: Expected end of string, got '.'") in Bundle:Admin:showTurnsFiltered.html.twig at line 75.

Что я делаю не так?

Комментарии:

1. Где именно вы получаете эту ошибку? Как вы используете свой оператор DQL?

2. Я использую его в репозитории классов, создаю его там и запускаю. Ошибка появляется в моем интерфейсе. Это часть функции фильтра, если я вызываю эту функцию, появляется ошибка сервера. Ни stacktrace, ни журнал ошибок не предоставляют полезной информации :/

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

4. Попробовал это, я снова получаю ту же ошибку, только вместо '.' есть expected FROM condition

Ответ №1:

Я нашел это сам после нескольких часов попыток и поиска, он работает с этим DQL :

 $dql = 'SELECT t, 
            SUM(CASE WHEN p.image = 1 THEN 1 ELSE 0 END) AS numImage
        FROM BundleEntityTurn t
            JOIN t.pois p
        GROUP BY t.id
        ORDER BY numImage DESC';  
  

Важно, что вам нужно использовать SUM вместо COUNT

Комментарии:

1. Спасибо, я не мог решить, куда поместить РЕГИСТР, поскольку это не сработало бы в предложении ORDER, независимо от того, что я пробовал! Я надеюсь, что в будущей версии они позволят использовать в предложении order.

2. Стоит отметить, что вы можете добавить HIDDEN, если не хотите, чтобы числовое изображение возвращалось в результатах. SELECT t, SUM(CASE WHEN p.image = 1 then 1 ELSE 0 END) AS HIDDEN numImage

3. Хотя замена COUNT на SUM работает в вашем случае, похоже, существует общая проблема с использованием частей CASE в DQL. Я открыл проблему для этого здесь: github.com/doctrine/doctrine2/issues/5915 Не стесняйтесь подписываться.

Ответ №2:

Вам нужно использовать ResultSetMappingBuilder. Это выглядело бы примерно так :

 public function getTurn()
{
    $rsm = new ResultSetMappingBuilder($this->_em);

    $rsm->addRootEntityFromClassMetadata('FooBarBundleEntityTurn', 't');
    $rsm->addJoinedEntityFromClassMetadata('FooBarBundleEntityPoi', 'p', 't', 'poi', array('id' => 'poi_id'));       
    $rsm->addScalarResult('ImageCount', 'ImageCount');


    $sql = 'SELECT t.id, t.foo, t.bar,
            SUM(CASE WHEN p.image = 1 then 1 else null end) ImageCount,                
            FROM Turn t   
            INNER JOIN poi p ON t.id = p.turn_id                
            ORDER BY ImageCount DESC';
    $query = $this->_em->createNativeQuery($sql, $rsm);

    return $query->getScalarResult();
}
  

примечание: возможно, вам потребуется изменить $query->getScalarResult() на $query->getResult() .

Комментарии:

1. Я не могу использовать NativeQuery, потому что я отправлю эти данные в пакет, который может работать только с Query объектами, но не с NativeQuery :-/

2. Спасибо за вашу помощь 🙂 У меня уже был NativeQuery, и было довольно неприятно видеть, что пакет не может с ним работать, но, к сожалению, я вынужден его использовать