【问题标题】:Symfony Doctrine - OrderBy after querySymfony Doctrine - 查询后的 OrderBy
【发布时间】:2017-04-17 10:52:30
【问题描述】:

我只想订购前一个主查询的结果。

我想要前 10 篇浏览次数最多的文章,然后按“添加日期”DESC 对其进行排序。

我知道诸如 orderBy 甚至 addOrderBy 之类的功能,但这不是我需要的,或者我没有正确实现它。

5 篇文章中获得前 2 名的示例:

  • 名称:一个||浏览量:100 ||添加时间:10/04/2017
  • 名称:b ||浏览量:10 ||添加时间:17/04/2017
  • 名称:c ||浏览量:50 ||添加时间:15/04/2017
  • 姓名:d ||浏览量:25 ||添加时间:12/04/2017
  • 名称:e ||浏览量:200 ||添加时间:05/04/2017

我首先提取最多的观点:

  1. e 条
  2. a 条

然后按addedAt date DESC(最近一次)排序:

  1. a 条
  2. e 条

我的查询:

public function findMostViewed($limit=10, $asArray=false)
{
        $qb = $this->createQueryBuilder('n')
            ->orderBy('n.nbViews', 'DESC')
            //->addOrderBy('n.addedAt', 'DESC')
            ->getQuery()
            ->setMaxResults($limit);

        return ($asArray) ? $qb->getResult(Query::HYDRATE_ARRAY) : $qb->getResult();
}

如果我知道如何执行 preSelectQuery,它可能会解决问题...

我想到了一个 SQL 查询:

SELECT ...
FROM ...
WHERE id IN(SELECT id FROM News ORDER BY nbViews DESC LIMIT 10)
ORDER BY addedAt DESC

【问题讨论】:

    标签: php doctrine-orm symfony-2.8


    【解决方案1】:

    您可以创建一个子查询并在您的主查询中使用它:

    public function findMostViewed($limit=10, $asArray=false)
    {
            $subqb = $this->createQueryBuilder('nn')
                ->orderBy('nn.nbViews', 'DESC')
                ->getQuery()
                ->setMaxResults($limit);
    
            $qb = $this->createQueryBuilder('n')
                ->where($qb->expr()->in('n.id', $subqb->getDQL())
                ->orderBy('n.addedAt', 'DESC')
                ->getQuery();
    
            return ($asArray) ? $qb->getResult(Query::HYDRATE_ARRAY) : $qb->getResult();
    }
    

    注意在子查询中使用nn 而不是n

    【讨论】:

    • 您的代码无效。试图调用类“Doctrine\ORM\QueryBuilder”的名为“getResult”的未定义方法。 Where In 条件必须是原因。即便如此,我还是根据您的示例自己解决了这个问题并更改了 IN 条件。谢谢:)
    【解决方案2】:

    也许如果你先使用'n.addedAt',然后使用'n.nbViews',像这样:

    $qb = $this->createQueryBuilder('n')
                ->orderBy('n.addedAt', 'DESC')
                ->addOrderBy('n.nbViews', 'DESC')
                ->getQuery()
                ->setMaxResults($limit);
    

    【讨论】:

    • 不,这不是我想要的。有了这个,我会得到最新的记录,如果没有类似“addat”的记录,第二个 orderBy 甚至都不会工作。
    【解决方案3】:

    根据 Veve 的回答,我更改了 WHERE IN 条件并设法使其工作。

    public function findMostViewed($limit=10, $asArray=false)
    {
            $subqb = $this->createQueryBuilder('nn')
                ->orderBy('nn.nbViews', 'DESC')
                ->getQuery()
                ->setMaxResults($limit);
    
            $qb = $this->createQueryBuilder('n')
                ->where('n.id IN (:ids)')
                ->setParameter('ids', array_values($subqb->getResult()))
                ->orderBy('n.addedAt', 'DESC')
                ->getQuery();
    
            return ($asArray) ? $qb->getResult(Query::HYDRATE_ARRAY) : $qb->getResult();
    }
    

    【讨论】:

      【解决方案4】:

      这也是工作。 如果您将 ->setFirstResult( '1' ) 添加到代码的 Israel Rodriguez Sanchez 作品中

      $qb = $this->createQueryBuilder('n')
      ->orderBy('n.addedAt', 'DESC')
      ->addOrderBy('n.nbViews', 'DESC')
      ->getQuery()
      ->setFirstResult( '1' )
      ->setMaxResults($limit);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-30
        • 1970-01-01
        相关资源
        最近更新 更多