【问题标题】:Order pagination result in Symfony 2Symfony 2 中的订单分页结果
【发布时间】:2018-01-30 10:54:46
【问题描述】:

我对 Symfony 2.7 中的分页顺序有疑问。

在使用分页之前,我们使用 PHP 函数 usort 对一些内容进行排序。但我现在的问题是,我们如何在学说查询中以与 usort 相同的顺序实现 usort。这需要与分页器一起工作。因为当我们现在使用查询(在下面)时,我们没有得到正确的结果。

排序函数:

        usort($result, function ($a, $b) {
        $aBegin = $a->getStartDate() ?: $a->getCreatedDate();
        $bBegin = $b->getStartDate() ?: $b->getCreatedDate();
        if ($aBegin < $bBegin) {
            return -1;
        }
        if ($aBegin == $bBegin) {
            return 0;
        }
        if ($aBegin > $bBegin) {
            return 1;
        }

        return 0;
    });

我们如何在以下查询中实现 usort:

    $build = $this->createQueryBuilder('building');
    $build
        ->addSelect('users', 'furniture')
        ->join('building.users', 'users')
        ->leftJoin('building.furniture', 'furniture')
        ->where('building.id = :id')
        ->setParameter('id', $id)
        ->orderBy('building.getStartDate', 'ASC')
        ->addOrderBy('building.getCreatedDate', 'DESC');

    $paginator = new Paginator($build->getQuery(), $fetchJoinCollection = true);
    $result = $paginator->getQuery()
        ->setFirstResult($offset)
        ->setMaxResults($limit)
        ->getResult();

谢谢!

教义orm:2.2.3, Symfony 版本:2.7

【问题讨论】:

  • 在您的usort 中,您使用$aBegin = $a-&gt;getStartDate() ?: $a-&gt;getCreatedDate();。因此,如果已设置开始日期,则考虑开始日期,如果未设置,则回退到创建日期。如果数据是一致的,我想你总是有startDate,它比createdDate 更新。是这样吗?
  • 附带说明,如果您希望获得分页结果,为什么要添加带有id 条件的where 子句?这样的查询将始终输出 1 或 0 个条目。
  • 当getStartDate = null 则需要先按getCreatedDate 排序。否则,只需对 getStartDate 进行排序。管理员接受时,开始日期不为空。

标签: php symfony doctrine-orm pagination doctrine-query


【解决方案1】:

要添加这样的条件,您可以在您的选择子句中使用CASE 表达式。您可以编写 CASE WHEN b.startDate IS NULL THEN b.createdDate ELSE b.startDate END 之类的内容来获得 usort 函数中描述的行为。

话虽如此,您不能简单地将其添加到您的 order by 子句中。您将需要选择此值,为其指定别名,然后根据新选择的值添加顺序。由于您可能不想获得 mixed result(您的实体将与标量值混合),因此您可以使用 HIDDEN 关键字从结果集中删除计算字段。

所有放在一起,它可能看起来像这样:

// $qb your query builder with all your other parameters
$qb->addSelect('CASE 
    WHEN building.startDate IS NULL 
        THEN building.createdDate 
        ELSE building.startDate
    END 
    AS HIDDEN beginDate');
$qb->orderBy('beginDate', 'DESC');

请注意,虽然这可行,但如果您的表中有很多条目,您可能会遇到性能问题,因为很可能会完全扫描整个表以执行此查询。

【讨论】:

  • 谢谢这是解决方案!
猜你喜欢
  • 1970-01-01
  • 2016-06-07
  • 2015-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多