【问题标题】:Querying average value from 2 tables with Symfony Doctrine使用 Symfony Doctrine 从 2 个表中查询平均值
【发布时间】:2015-06-12 16:09:28
【问题描述】:

我使用 Symfony 2.6 和 Doctrine 作为 ORM。该项目在 Apache + MySQL 上运行。

我的数据库中有 2 个实体:图书和评级。我正在构建一个系统,用户可以在其中对书籍从 0 到 100 进行评分。

我的实体:

  • 书籍:id,其他不相关的字段
  • 评分:id、book_id、score、其他不相关的字段

每本书可以有多个评分,但评分只能与一本书相关(一对多映射)。

我的目标是按平均评分排序前 5 本书。

例子:

  • 书 1:94.5
  • 书 2:93.3
  • 书 3:89.2
  • 书 4:85.2
  • 书 5:79.6

我已经尝试使用两个实体的双循环来获得结果,但是根据 Symfony 分析器,它需要 3.7 秒并且需要 1001 次查询,这是非常低效的。我很确定可以使用 DQL 以更好的方式完成,所以...

实现我的目标最有效的方法是什么(如果可能在单个查询中)?

编辑

感谢 MikO 朝着正确的方向前进。需要在 FROM 和 JOIN 语句中编写完整的实体(如 AcmeBundle:Book)才能使其工作。此外,您不能在查询构建器中使用 LIMIT,因此在构建查询之后调用结果之前,我必须使用 setMaxResults(5) 才能仅检索前 5 本书。

【问题讨论】:

    标签: php mysql symfony doctrine-orm dql


    【解决方案1】:

    我实际上并没有尝试过,但我会为您的 Book 实体创建一个 custom repository class,然后我会在其中写下类似的内容:

    public function getTopRatedBooks()
    {
        $em = $this->getEntityManager();
    
        $query = $em->createQuery('
          SELECT book.id, book.name, AVG(rating.score) as avg_rating
          FROM book 
          JOIN rating
          WHERE book.id = rating.book_id
          GROUP BY book.id
          ORDER BY avg_rating DESC
        ');
    
        $result = $query->getResult();
    
        return $result;
    }
    

    【讨论】:

    • 您的猜测几乎是正确的。玩了一会儿,我找到了正确的句子:` SELECT Book.id, Book.name, AVG(Rating.score) as avg_score FROM AcmeBundle:Book Book JOIN AcmeBundle:Rating Rating WHERE Book.id = Rating。 book GROUP BY Book.id ORDER BY avg_score DESC `如果我尝试在末尾添加'LIMIT 5',唯一剩下的问题会发生,我得到一个语法异常:预期的字符串结尾,得到'LIMIT'知道为什么LIMIT没有'不行吗?
    • 对不起之前的代码,它没有让我正确编辑它,我也没有设法将它格式化为代码(这个评论系统太复杂了,我不需要除了我已经知道的以外,再学习其他语言:)) 我想以更好的格式向您展示代码,但无论如何我相信您可以像现在一样理解它。
    • 没关系,我找到了解决方案,感谢您的帮助和时间。
    • @BestBloodyDay 不客气 - 我很高兴它有帮助!
    猜你喜欢
    • 2014-01-26
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多