2011-11-16 44 views
3

我有一个使用MAX() MySQL的柱为其中一列提供的数据的CGridView。我有与排序工作,但我无法弄清楚过滤。我认为我可以使用CDbCriteria::compare()调用来设置它,但它不起作用。想法?CGridView滤波与骨料(分组)的功能 - 例如MAX()

我的搜索功能:

$criteria = new CDbCriteria; 
    $criteria->condition = 't.is_deleted = 0 and is_admin = 0'; 
    // get last note date 
    $criteria->select = array('t.*', 'MAX(n.visit_date) AS last_note'); 
    $criteria->join = 'LEFT JOIN notes n ON t.id = n.distributor_id'; 
    $criteria->group = 't.id'; 
    $criteria->order = 't.status'; 

    $criteria->compare('t.type', $this->type); 
    $criteria->compare('t.name', $this->name, true); 
    $criteria->compare('t.city', $this->city, true); 
    $criteria->compare('t.state', $this->state); 
    $criteria->compare('last_note', $this->last_note); 



    return new CActiveDataProvider('Distributor', array(
      'criteria' => $criteria, 
      'pagination' => array(
       'pageSize' => 20 
      ), 
      'sort' => array(
       'defaultOrder' => 'name', 
       'attributes' => array(
        'last_note' => array(
         'asc' => 'last_note', 
         'desc' => 'last_note DESC' 
        ), 
       ) 
      ), 
     )); 

在我看来,我只是设置名称和值值。

我得到的错误是CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'last_note' in 'where clause'

编辑:我发现,要做到这一点(因为你不能在where子句中聚合函数)的唯一方法是检查$_GET阵列的last_note值,添加一个条款。请注意,这不是参数或任何东西,我只是想粗略出来,看看它是否会工作:

if(isset($_GET['Distributor']['last_note']) && $_GET['Distributor']['last_note'] != '') { 
     $criteria->having = 'MAX(n.visit_date)=\'' . $this->last_note . "'"; 
} 

我讨厌这样的模型中使用的请求变量,但没有太多否则我可以做。

回答

3

你在正确的轨道上。您可以使用having过滤聚合函数,如MAX()SUM()。在这样的查询,你应该添加一个group,否则你会在你的结果了很多的重复数据结束时,经销商有在同一天多个音符(假设t.id是主键)。其次,您应该使用命名参数,而不是直接将变量放入SQL中。所以,相反的compare('last_note'...你最终的东西是这样的:

$criteria->group = 't.id'; 
$criteria->having = 'MAX(n.visit_date) = :last_note'; 
$criteria->params = array(':last_note' => $this->last_note); 
2

为了筛选工作,你应该有一个class属性来存储数据:

公共$ last_note;

否则$这个 - > last_note不会返回任何东西,你的$基准 - - >比较( 'last_note',$这个 - > last_note);不会做任何事情