【问题标题】:CGridView filtering with aggregate (grouping) functions - eg MAX()使用聚合(分组)函数进行 CGridView 过滤 - 例如 MAX()
【发布时间】:2011-12-30 11:59:56
【问题描述】:

我有一个 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 . "'";
}

我讨厌像这样在模型中使用请求变量,但我无能为力。

【问题讨论】:

    标签: php yii


    【解决方案1】:

    你在正确的轨道上。您可以使用 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】:

      为了过滤工作,你应该有一个类属性来存储数据:

      公开 $last_note;

      否则 $this->last_note 不会返回任何内容,而您的 $criteria->compare('last_note', $this->last_note);也不会做任何事

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-24
        • 2014-09-18
        • 2017-09-10
        • 2015-05-19
        • 2017-07-03
        相关资源
        最近更新 更多