我有一个CGridView,它使用MAX()
mysql列为其中一列提供数据。我有使用排序,但我无法弄清楚过滤。我假设我可以使用CDbCriteria::compare()
调用来设置它,但它不起作用。想法?
我的搜索功能:
$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值,并添加having子句。请注意,这不是参数化或任何其他内容,我只是想粗略地看看它是否可行:
if(isset($_GET['Distributor']['last_note']) && $_GET['Distributor']['last_note'] != '') {
$criteria->having = 'MAX(n.visit_date)=\'' . $this->last_note . "'";
}
我讨厌在模型中使用这样的请求变量,但我没有其他的东西可以做。
答案 0 :(得分:3)
你走在正确的轨道上。您可以使用MAX()
过滤SUM()
和having
等汇总函数。在这样的查询中,您应该添加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);
答案 1 :(得分:2)
为了使过滤工作,你应该有一个class属性来存储数据:
public $ last_note;
否则$ this-> last_note不会返回任何内容和你的$ criteria-> compare('last_note',$ this-> last_note);什么都不做