2

我有一个Person可以接收多种类型的Income. 我希望能够返回所赚取的SUM收入,按每个Income Type.

+---------------+-----------------+
| INCOME TYPE   | SUM AMOUNT      |
+---------------+-----------------+
| Salary        | $934.33         |
| Gambling      |  $27.99         |
| Tips          | $584.00         |
+---------------+-----------------+        

我已经能够获得一个self::STAT关系查询来提供收到的总收入(1546.32 美元),但没有按Income Type.

结果,我试图将其作为模型中的self::HAS_MANY关系查询来执行Person,如下所示:

  public function relations() {
     return array(
        'incomes_total' => array(
           self::HAS_MANY,
           'Income',
           'person_id',
           'select' => array('income_type_id', 'SUM(amount) AS total'),
           'group' => "income_type_id"
     ));
  }

这将导致生成以下 SQL:

SELECT
  "incomes_total"."income_type_id" AS "t1_c5"
, SUM(amount) AS total
, "incomes_total"."id" AS "t1_c0"
FROM "stwd_income" "incomes_total"
WHERE ("incomes_total"."person_id"=:ypl0)
GROUP BY income_type_id

这非常接近所需的查询。

我无法弄清楚为什么在, "incomes_total"."id" AS "t1_c0"其中添加了该行。我不想要那个。它导致CDbException错误:

CDbCommand failed to execute the SQL statement: 
SQLSTATE[42803]: Grouping error: 7 ERROR: column "incomes_total.id" must 
appear in the GROUP BY clause or be used in an aggregate function.

如何实现我需要的查询类型?

更新 1: Active Record 和自定义 SQL 查询之间的区别开始变得清晰,并且 Active Record 可能不适合这样的任务。

4

1 回答 1

1

就我个人而言,除了非常基本的查询和 CRUD 之外,我不会将 ActiveRecord 用于其他任何事情。即使存在 STAT 关系,它们也更适合用于简单的计数或求和。HAS_MANY 关系在任何方面都是错误的,因为您不期望有一系列模型,是吗?您只需要一个简单的 id 和总和数组,因此在您的情况下,我只需在 Person 模型中创建一个方法,如下所示

private $_salaryInfo;

public function getSalaryInfo()
{
    //cache the value if possible to save unnecessary queries
    if(isset($this->_salaryInfo))
        return $this->_salaryInfo;

    //query database
    $command = Yii::app()->db->createCommand();
    $command->select('income_type_id, SUM(amount)')->where('person_id = '.$this->id)->groupBy('income_type_id');
    return $this->_salaryInfo = $command->queryAll();
}

你现在应该可以做

foreach($person->salaryInfo as $type_id => $sum)
于 2013-02-11T15:15:13.573 回答