Доктрина 2 DQL CASE WHEN in Count

Имам тази заявка в родния код на 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 Bundle\Entity\Poi p.image = 1 then 1 ELSE NULL END)) AS num
FROM Bundle\Entity\Turn 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.

какво правя грешно


person KhorneHoly    schedule 04.07.2014    source източник
comment
Къде точно получаваш тази грешка? Как използвате вашия DQL оператор?   -  person Rybus    schedule 04.07.2014
comment
Използвам го в хранилището на класа, създавам го там и го стартирам. Грешката се появява в моя интерфейс. Това е част от филтърна функция, ако извикам тази функция, се появява сървърна грешка. Нито stacktrace, нито регистърът на грешките предоставят полезна информация:/   -  person KhorneHoly    schedule 04.07.2014
comment
Какво ще кажете да премахнете едно ( и ), тъй като използвате две скоби :/ Наистина изглежда проблем със синтаксиса, тъй като заявката ви изглежда добре.   -  person Rybus    schedule 04.07.2014
comment
Опитах това, отново получавам същата грешка, само че вместо '.' има expected FROM condition   -  person KhorneHoly    schedule 04.07.2014


Отговори (2)


Намерих го сам след часове опити и търсене, работи с този DQL:

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

Важно е, че трябва да използвате SUM вместо COUNT

person KhorneHoly    schedule 04.07.2014
comment
Благодаря ви, не можах да разбера къде да поставя CASE, тъй като нямаше да работи в клаузата ORDER, независимо какво опитвах! Надявам се в бъдеща версия да направят възможно използването в клаузата за поръчка. - person Scott Flack; 09.03.2015
comment
Струва си да се отбележи, че можете да добавите HIDDEN, ако не искате numImage да се връща в резултатите. SELECT t, SUM(CASE WHEN p.image = 1 then 1 ELSE 0 END) AS HIDDEN numImage - person David Stone; 11.07.2015
comment
Въпреки че замяната на COUNT със SUM работи във вашия случай, изглежда има общ проблем с използването на CASE части в DQL. Отворих проблем за него тук: github.com/doctrine/doctrine2/issues/5915 Чувствайте се свободни да се абонирате. - person webDEVILopers; 03.07.2016

Трябва да използвате ResultSetMappingBuilder. Ще изглежда нещо като:

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

    $rsm->addRootEntityFromClassMetadata('Foo\BarBundle\Entity\Turn', 't');
    $rsm->addJoinedEntityFromClassMetadata('Foo\BarBundle\Entity\Poi', '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().

person Rybus    schedule 04.07.2014
comment
Не мога да използвам NativeQuery, защото ще изпратя тези данни към пакет, който може да работи само с Query обекти, но не и с NativeQuery :-/ - person KhorneHoly; 04.07.2014
comment
Благодаря за помощта :) Вече имах NativeQuery и беше доста разочароващо да видя, че Bundle не може да работи с него, но за съжаление съм принуден да го използвам - person KhorneHoly; 04.07.2014