如何在Doctrine2中按案例排序(Symfony2)

时间:2013-12-10 07:51:45

标签: php mysql symfony doctrine-orm case-when

我想在Symfony 2.3中使用Doctrine来运行此查询。但似乎Doctrine不理解CASE声明。有人可以帮忙吗?提前谢谢!

SELECT max(id) id, name
FROM cards
WHERE name like '%John%'
GROUP BY name
ORDER BY CASE WHEN name like 'John %' THEN 0
           WHEN name like 'John%' THEN 1
           WHEN name like '% John%' THEN 2
           ELSE 3
      END, name

4 个答案:

答案 0 :(得分:43)

如果您使用的是createQueryBuilder,那么您可以使用类似

$query->addSelect("(CASE WHEN name like 'John %' THEN 0
           WHEN name like 'John%' THEN 1
           WHEN name like '% John%' THEN 2
           ELSE 3 END) AS HIDDEN ORD ");
$query->orderBy('ORD', 'DESC');

请注意,您必须拥有“HIDDEN”。

您也可以使用doctrine本机查询。

答案 1 :(得分:1)

CASE是特定于供应商的,并且原则上不受原则支持。

如果结果很小,我的建议是拉出整个结果集,然后对数组进行排序。

如果结果集太大,您应该编写本机查询并为实体加水。有关详细信息,请参阅Doctrine Documentation on Native SQL。它看起来很可怕,但是一旦你走过一个例子就有意义了。

作为最后的手段,您可以绕过doctrine并使用低级本机SQL。有关详细信息,请参阅this post

我知道Doctrine Extensions has an IfElse function可能有用,但我没有听过很多成功案例。

答案 2 :(得分:0)

如果不存在任何关系,则按关系表或本地列进行订购时,这为我完成了工作:

$doctrineQuery->add('orderBy', '(CASE WHEN COUNT(relation_table.uid)>0 THEN relation_table.price ELSE current_table.generic_price END) ASC');

答案 3 :(得分:0)

我有类似的问题,我必须在结果的顶部加上几个数字前缀。 所以我这样解决:

    $qb = $this->createQueryBuilder('numberPrefix');
    $qb
        ->select('country.code','numberPrefix.prefix')
        ->addSelect('
            (CASE WHEN country.code = :firstCountryCode THEN 1
            WHEN country.code = :secondCountryCode THEN 2
            WHEN country.code = :thirdCountryCode THEN 3
            WHEN country.code = :fourthCountryCode THEN 4
            ELSE 5 END) AS HIDDEN ORD')
        ->innerJoin('numberPrefix.country','country')
        ->orderBy('ORD, country.id')
        ->setParameters(
            [
                'firstCountryCode' => $firstCountryCode,
                'secondCountryCode' => $secondCountryCode,
                'thirdCountryCode' => $thirdCountryCode,
                'fourthCountryCode' => $fourthCountryCode,
            ]
        );