Symfony3-Doctrine:按案例排序

时间:2018-11-27 10:37:26

标签: mysql doctrine-orm sql-order-by symfony-3.4 doctrine-query

我正在研究Symfony 3.4项目。

我想按updated_at(如果存在)排序表(不为null),否则按created_at排序。

在SQL中,这可行:

SELECT * FROM `contract`
ORDER BY
  (CASE WHEN ISNULL(`updated_at`) THEN `created_at` ELSE `updated_at` END)
DESC 

我尝试了很多事情,但是我无法使其与Doctrine Query Builder一起使用。

首先,我尝试了此操作(语法错误):

$contracts = $em->createQuery(
    'SELECT c
    FROM AppBundle:Contract c
    ORDER BY (CASE WHEN c.updatedAt = :update THEN c.createdAt ELSE c.updatedAt END) DESC')
->setParameter('update', NULL)
->getResult();

然后,我根据this topic进行了尝试,但没有结果(没有错误):

$contracts = $rp->createQueryBuilder('c')
    ->select('(CASE WHEN c.updatedAt != :update THEN 1 ELSE 0 END) AS HIDDEN orderDate')
    ->orderBy('orderDate', 'DESC')
    ->addOrderBy('c.createdAt', 'DESC')
    ->setParameter('update', NULL)
    ->getQuery()->getResult();

如果合同已被更新,如何按合同的更新日期排序;如果合同未被修改,如何按合同的创建日期排序?

如果有帮助,我将DoctrineExtensions bundle用于其他查询,我看到了IfNullIfElse类,但是在我的案例中我不怎么使用它们。

1 个答案:

答案 0 :(得分:0)

经过几次尝试,我终于找到了解决方法。

使用@provider:返回列表中第一个不为null的值,因此,如果A为null而B不为null,则 const data = [ { orderType: "orderType1", orderCount: 0, orderDate: 47 }, { orderType: "orderType1", orderCount: 21, orderDate: 47 }, { orderType: "orderType1", orderCount: 3, orderDate: 47 }, { orderType: "orderType1", orderCount: 5, orderDate: 48 }, { orderType: "orderType1", orderCount: 32, orderDate: 48 }, { orderType: "orderType1", orderCount: 12, orderDate: 48 }]; let foundIdx; var result = data.reduce((accu, curr, idx, arr) => { if (accu.some((value, resIdx, reArr) => { // present in out array? foundIdx = resIdx; return (value.orderType == curr.orderType && value.orderDate == curr.orderDate); })) { // already present, increment OrderCount accu[foundIdx].orderCount += curr.orderCount; } else { // not yet present push the element accu.push(curr); } return accu; }, []); console.log(JSON.stringify(result)); //[{"orderType":"orderType1","orderCount":24,"orderDate":47},{"orderType":"orderType1","orderCount":49,"orderDate":48}] 将返回B。

COALESCE

无需使用DoctrineExtensions捆绑包。