如何在CDbCriteria中使用此SQL

时间:2016-03-24 09:31:29

标签: php sql yii

我目前有这个SQL

 SELECT


       MAX(CASE WHEN uv.user_type_variables_id = 1 THEN uv.value ELSE NULL END) Question1,
       MAX(CASE WHEN uv.user_type_variables_id = 2 THEN uv.value ELSE NULL END) Question2,
       MAX(CASE WHEN uv.user_type_variables_id = 3 THEN uv.value ELSE NULL END) Question3,
       MAX(CASE WHEN uv.user_type_variables_id = 4 THEN uv.value ELSE NULL END) Question4,
       MAX(CASE WHEN uv.user_type_variables_id = 5 THEN uv.value ELSE NULL END) Question5,
       MAX(CASE WHEN uv.user_type_variables_id = 6 THEN uv.value ELSE NULL END) Question6

       FROM tbl_event_attendees AS ea

       LEFT JOIN tbl_user AS u ON ea.user_id = u.id
       LEFT JOIN tbl_event AS e ON ea.event_id = e.id                  
       LEFT JOIN tbl_user_variables AS uv on u.id = uv.user_id

       GROUP BY ea.id

我需要把它放到我现有的CDbCriteria +扩展关系中。我需要将每个问题1到6作为一个变量,我可以使用它来放入cgridview但是我很难让它运行起来。如果我使用CSQLdataprovider它工作正常但我需要现有的标准。

我目前的标准

  public function search() {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria = new CDbCriteria;

        $criteria->compare('id', $this->id, true);
        $criteria->compare('event_id', $this->event_id, true);
        $criteria->compare('status_id', $this->status_id, true);
        $criteria->compare('checkin_status_id', $this->checkin_status_id, true);
//        $criteria->compare('guest_invites', $this->guest_invites, true);
        $criteria->compare('guest_of_user_id', $this->guest_of_user_id, true);
        $criteria->compare('user_id', $this->user_id, true);
        $criteria->compare('assign_group', $this->assign_group, true);

//        $criteria->with = 'eventAttendeesGroup';
        $criteria->with = 'user';
        $criteria->compare('user.forename', $this->user_forename, true);
        $criteria->compare('user.surname', $this->user_surname, true);
        $criteria->compare('user.company', $this->user_company, true);
        $criteria->compare('user.telephone', $this->user_telephone, true);
        $criteria->compare('user.dob', $this->user_dateofbirth, true);

        //need to get rid of this
        $criteria->compare('userVariables.value', $this->userType_value, true);

        $criteria->order = 'user.surname ASC';

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
            //manages the pagination and how many users appear on the onsite reg page 
            'pagination'=>array('pageSize'=>50),
            //'pagination'=>false,
        ));
    }

有人有任何想法吗?

我认为我必须为每个问题设置变量,并将它们添加到像usertype.variable和$ this->变量之类的关系中,但总是丢失。

修改。

我可以

     function newsearch(){
     $rawData=Yii::app()->db->createCommand('SELECT


                    MAX(CASE WHEN uv.user_type_variables_id = 1 THEN uv.value ELSE NULL END) Question1,
                    MAX(CASE WHEN uv.user_type_variables_id = 2 THEN uv.value ELSE NULL END) Question2,
                    MAX(CASE WHEN uv.user_type_variables_id = 3 THEN uv.value ELSE NULL END) Question3,
                    MAX(CASE WHEN uv.user_type_variables_id = 4 THEN uv.value ELSE NULL END) Question4,
                    MAX(CASE WHEN uv.user_type_variables_id = 5 THEN uv.value ELSE NULL END) Question5,
                    MAX(CASE WHEN uv.user_type_variables_id = 6 THEN uv.value ELSE NULL END) Question6

                    FROM tbl_event_attendees AS ea

                    LEFT JOIN tbl_user AS u ON ea.user_id = u.id
                    LEFT JOIN tbl_event AS e ON ea.event_id = e.id                  
                    LEFT JOIN tbl_user_variables AS uv on u.id = uv.user_id

                    GROUP BY ea.id')->queryAll();
// or using: $rawData=User::model()->findAll();
return  $dataProvider=new CArrayDataProvider($rawData, array(
    'id'=>'Questions',
    'sort'=>array(
        'attributes'=>array(
             'Question1', 'Question2', 'Question3',
        ),
    ),
    'pagination'=>array(
        'pageSize'=>10,
    ),
));

要在网格中显示sql,但我仍然无法访问我的模型数据。

2 个答案:

答案 0 :(得分:0)

我没有彻底测试过。但是您需要将属性添加到模型类并将查询select语句添加到CDbCriteria(select)属性并使用together属性,以便立即执行查询。

我假设这是tbl_event_attendees模型,正确使用时Yii会自动填充记录

class tblEventAttendees  extends CActiveRecord { 

public $Question1;
public $Question2;
public $Question3;
public $Question4;
public $Question5;
public $Question6;

...


    public function search() {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria = new CDbCriteria;
        $criteria->select = [
            't.*',
            'user.*',
            'MAX(CASE WHEN uv.user_type_variables_id = 1 THEN uv.value ELSE NULL END) Question1',
            'MAX(CASE WHEN uv.user_type_variables_id = 2 THEN uv.value ELSE NULL END) Question2',
            'MAX(CASE WHEN uv.user_type_variables_id = 3 THEN uv.value ELSE NULL END) Question3',
            'MAX(CASE WHEN uv.user_type_variables_id = 4 THEN uv.value ELSE NULL END) Question4',
            'MAX(CASE WHEN uv.user_type_variables_id = 5 THEN uv.value ELSE NULL END) Question5',
            'MAX(CASE WHEN uv.user_type_variables_id = 6 THEN uv.value ELSE NULL END) Question6',
            // add what you need
        ];

        $criteria->compare('id', $this->id, true);
        $criteria->compare('event_id', $this->event_id, true);
        $criteria->compare('status_id', $this->status_id, true);
        $criteria->compare('checkin_status_id', $this->checkin_status_id, true);
//        $criteria->compare('guest_invites', $this->guest_invites, true);
        $criteria->compare('guest_of_user_id', $this->guest_of_user_id, true);
        $criteria->compare('user_id', $this->user_id, true);
        $criteria->compare('assign_group', $this->assign_group, true);

//        $criteria->with = 'eventAttendeesGroup';
        $criteria->compare('user.forename', $this->user_forename, true);
        $criteria->compare('user.surname', $this->user_surname, true);
        $criteria->compare('user.company', $this->user_company, true);
        $criteria->compare('user.telephone', $this->user_telephone, true);
        $criteria->compare('user.dob', $this->user_dateofbirth, true);

        //need to get rid of this
        $criteria->compare('userVariables.value', $this->userType_value, true);

        $criteria->order = 'user.surname ASC';

        $criteria->with = array('user','event','userVariables');
        $criteria->together = true;

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
            //manages the pagination and how many users appear on the onsite reg page
            'pagination'=>array('pageSize'=>50),
            //'pagination'=>false,
        ));
    }

<强>更新

经过一些测试后,我们发现问题不在查询中,而是在使用别名时。 Yii使用别名映射查询结果,并使用preg_match函数从查询中提取别名,请参阅https://github.com/yiisoft/yii/blob/1.1.17/framework/db/ar/CActiveFinder.php#L954

所以改变这个

$criteria->select = [
    't.*',
    'user.*',
    'MAX(CASE WHEN uv.user_type_variables_id = 1 THEN uv.value ELSE NULL END) Question1',
    'MAX(CASE WHEN uv.user_type_variables_id = 2 THEN uv.value ELSE NULL END) Question2',
    'MAX(CASE WHEN uv.user_type_variables_id = 3 THEN uv.value ELSE NULL END) Question3',
    'MAX(CASE WHEN uv.user_type_variables_id = 4 THEN uv.value ELSE NULL END) Question4',
    'MAX(CASE WHEN uv.user_type_variables_id = 5 THEN uv.value ELSE NULL END) Question5',
    'MAX(CASE WHEN uv.user_type_variables_id = 6 THEN uv.value ELSE NULL END) Question6',
    // add what you need
];

为此解决了问题

$criteria->select = [
    't.*',
    'user.*',
    'MAX(CASE WHEN uv.user_type_variables_id = 1 THEN uv.value ELSE NULL END) AS Question1',
    'MAX(CASE WHEN uv.user_type_variables_id = 2 THEN uv.value ELSE NULL END) AS Question2',
    'MAX(CASE WHEN uv.user_type_variables_id = 3 THEN uv.value ELSE NULL END) AS Question3',
    'MAX(CASE WHEN uv.user_type_variables_id = 4 THEN uv.value ELSE NULL END) AS Question4',
    'MAX(CASE WHEN uv.user_type_variables_id = 5 THEN uv.value ELSE NULL END) AS Question5',
    'MAX(CASE WHEN uv.user_type_variables_id = 6 THEN uv.value ELSE NULL END) AS Question6',
    // add what you need
];

答案 1 :(得分:0)

我建议你创建一个MYSQL database view并在Yii模型中使用它。使用此方法,您可以使用所有Yii模型功能,例如任何其他基于表格的模型(INSERT,UPDATE,DELETE操作除外),保留原始查询和条件中的现有功能:

CREATE OR REPLACE VIEW myviewname AS 
... your SQL ...

创建MYSQL database view后,make sure to create Yii model用于数据库视图。在此模型中,使用现有的自定义search()。最后根据需要在程序中使用它,例如在CGridView,报告等中