php - Symfony Doctrine 查询通过子查询计算组后的排名

标签 php orm symfony1 doctrine rank

我正在使用 Symfony 1.4 和 Doctrine 1.2 ORM 构建应用程序。我对 ORM Doctrine 还很陌生,正在掌握它的窍门,但我无法完全解决这个问题。

我有一张用户分数表 (mbScoreByGenre),其中一个用户 ID 可以拥有一个 parent_genre 的多条用户分数记录。即 - 多对多

我的目标是根据特定用户对给定 parent_genre_id 和 user_id 的累积分数来查找其排名。我的排名算法使用子查询,我在构建有效的 Doctrine 查询时遇到了很多麻烦。

这是我的 mbScoreByGenre Doctrine 架构

mbScoreByGenre:
  actAs:
    Timestampable: ~    
  columns:

    id:                 { type: integer, primary: true, autoincrement: true }
    user_id:            { type: integer, notnull: true }
    genre_id:           { type: integer, notnull: true } 
    parent_genre_id:    { type: integer, notnull: true } 
    score:              { type: float, notnull: true, default: 0  } 

一个。首先我尝试做这样的事情:

$q = Doctrine_Query::create()
    ->select('((SELECT COUNT(1) AS num 
        FROM 
        (SELECT SUM(mbScoreByGenre.score) 
        WHERE SUM(mbScoreByGenre.score) > SUM(s.score)
        AND mbScoreByGenre.parent_genre_id = '.$genre['parent_id'].'
        AND s.parent_genre_id = '.$genre['parent_id'].'
        GROUP BY mbScoreByGenre.user_id
        ) + 1)  AS rank')
    ->from('mbScoreByGenre s')
    ->where('s.user_id = ?', array($user_id))
    ->groupBy('s.user_id')
    ->orderBy('rank');

but I got the following error Fatal error: Maximum function nesting level of '100' reached, aborting! in \lib\vendor\symfony-1.4.14\lib\plugins\sfDoctrinePlugin\lib\vendor\doctrine\Doctrine\Query\Tokenizer.php on line 303. I don't understand how to build the subquery so that it works.

B.所以后来我改变并尝试了一种不同的方法

$q = new Doctrine_RawSql();
$q  ->addComponent('s', 'mbScoreByGenre')
    ->select('COUNT({*}) AS {rank}')
    ->from('(SELECT SUM(s.score) AS total_score
        FROM mb_score_by_genre s
        WHERE s.parent_genre_id = '.$genre['parent_id'].'
        GROUP BY s.user_id)
            ')
    ->where('total_score >= (
        SELECT SUM(s.score) 
        FROM mb_score_by_genre s
        WHERE s.parent_genre_id = '.$genre['parent_id'].'
        AND s.user_id = '.$user_id.'
        GROUP BY s.user_id
    )');

但我得到这个错误:Sql 查询中的所有选定字段必须采用 tableAlias.fieldName 格式。我使用 Doctrine_RawSql 的原因是我读到 doctrine 1.2 不支持 From 中的子查询。对于这种方法,我不知道如何引用 tableAlias.fieldName 格式中的“total_score”列。我是否必须添加一个空白组件来引用为“total_score”返回的子查询表?

C.最后,我尝试将子查询作为 Doctrine 查询运行,并通过计算查询返回的 Doctrine 对象行来计算排名。

$q = Doctrine_Query::create()
    ->select('SUM(s.score)')
    ->from('mbScoreByGenre s')
    ->where('s.parent_genre_id = ?', $genre['parent_id'])
    ->andWhere('SUM(s.score) > (
        SELECT SUM(p.score) 
        FROM mbScoreByGenre p
        WHERE p.parent_genre_id = '.$genre['parent_id'].'
        AND p.user_id = '.$user_id.'
        GROUP BY p.user_id
    )')
    ->groupBy('s.user_id'); 

    $result = $q->execute();

但它给了我错误:

SQLSTATE[HY000]: General error: 1111 Invalid use of group function. Is it because groupBy('s.user_id') and GROUP BY p.user_id, both p and s refer to the same model?

我在网上进行了大量搜索以寻找答案,但我似乎无法找到 3 种方法中任何一种的答案。

任何帮助都会很棒。欣赏它。

最佳答案

也许,我没有完全理解您真正需要的是什么,但是您尝试过 HAVING 子句吗? WHERE 子句不支持像 SUM() 这样的聚合函数。 我尝试了这段代码,它起作用并返回了一些值,但我不能确定这是否是您需要的:

$q = Doctrine_Query::create()
  ->select('count(*)')
  ->from('mbScoreByGenre s')
  ->where('s.parent_genre_id = ?', $genre['parent_id'])
  ->having("SUM(s.score) > (
    SELECT SUM(p.score) 
    FROM mbScoreByGenre p 
    WHERE p.parent_genre_id = {$genre['parent_id']}
      AND p.user_id = {$user_id})")
->groupBy('s.user_id');

$result = $q->execute(array(), Doctrine::HYDRATE_SCALAR);
var_dump($result);

如果这不是您需要的 - 尝试更准确地解释。

关于php - Symfony Doctrine 查询通过子查询计算组后的排名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9900737/

相关文章:

css - Symfony 表单标签的自定义 CSS 类?

symfony1 - 如何利用转义来防止XSS攻击?

symfony1 - 如何创建需要访问其他字段值的 Symfony 验证器?

php - "Notice: Undefined variable"、 "Notice: Undefined index"、 "Warning: Undefined array key"和 "Notice: Undefined offset"使用 PHP

php - 当有 DB::select() 时如何使用 Laravel 关系?

php - 我的 require_once 路径有什么问题?

sql - LLblgen : Select distinct?

c# - 如何在 C# 中实现 ORM

php - 脚本运行时加载栏

php - 从 Stripe 获取发票