如何将原始SQL转换为Yii2,例如查找查询

时间:2019-03-31 17:07:52

标签: mysql sql yii2

我无法将原始SQL查询转换为类似Yii2的方法。我想通过过滤和排序从RAW sql实现网格视图。我在ModelSearch中使用ActiveDataProvider和Yii默认方法。

我确实尝试过使用Model :: findBySql,但是它不允许我在网格视图中对结果进行过滤或排序。我不想使用SQLDataProvider,因为我的查询中有关系。

我看到将Model :: FindBySql($ sql)更改为Model :: find让我进行排序和过滤,但结果与预期的不同。我必须转换此SQL以使用Model :: Find()方法

我努力改变的SQL是

$sql = 'SELECT A.*, (6371 * acos(cos(radians("'.$mapSearch->gps_lat.'")) * cos(radians(gps_lat))*cos(radians(gps_long)-radians("'.$mapSearch->gps_long.'"))+sin(radians("'.$mapSearch->gps_lat.'"))*sin(radians(gps_lat)))) AS distance FROM address A JOIN contest_has_address CA On A.id = CA.address_id JOIN contest C On C.id = CA.contest_id JOIN contest_has_date CD On C.id = CD.contest_id JOIN date D On D.id = CD.date_id WHERE main = 1 AND C.status = 1 AND D.start_time > "'.$today.'" HAVING distance < "'.$mapSearch->distance.'" ORDER BY distance ASC';

我的控制器:

if($mapSearch->save(false)) {
                $lat = $mapSearch->gps_lat;
                $long = $mapSearch->gps_long;
                $sql = 'SELECT A.*, (6371 *     acos(cos(radians("'.$mapSearch->gps_lat.'")) *      cos(radians(gps_lat))*cos(radians(gps_long)-    radians("'.$mapSearch->gps_long.'"))+sin(radians("'.$mapSearch->gps_lat.'")    )*sin(radians(gps_lat)))) AS distance FROM address A JOIN     contest_has_address CA On A.id = CA.address_id JOIN contest C On C.id =     CA.contest_id JOIN contest_has_date CD On C.id = CD.contest_id JOIN date D     On D.id = CD.date_id WHERE main = 1 AND C.status = 1 AND D.start_time >     "'.$today.'" HAVING distance < "'.$mapSearch->distance.'" ORDER BY distance     ASC';
                $models =     Address::findBySql($sql)->all(); 
                $count =     Yii::$app->db->createCommand($sql)->queryScalar();
                $dataProvider =     $searchModel->searchMapAddress(Yii::$app->request->queryParams, $sql);


 return $this->render('map', [
                    'sql'=>$sql,
                    'searchModel'=>$searchModel,
                    'models'=>$models,
                    'dataProvider'=>$dataProvider,
                    'mapSearch'=>$mapSearch,
                    'lat'=>$mapSearch->gps_lat,
                    'long'=>$mapSearch->gps_long,
                ]);

我的模特

$query = Address::findBySql($sql);
    $query->joinWith(['contest']);

    $dataProvider = new ActiveDataProvider([
        'query' => $query,
    ]); 

并查看:

echo GridView::widget([
                    'dataProvider' => $dataProvider,
                    'filterModel' => $searchModel,
                    'layout'=> '{items}',

1 个答案:

答案 0 :(得分:1)

假设您的原始SQL查询正常运行,则可以使用ActiveRecordQuery Builder创建查询。

要在查询中使用MYSQL函数,必须使用\yii\db\Expresion,而在构建查询时,应在查询结束时使用->createCommand()->rawSQL,并用->one()或{{1}代替},然后回显查询以查看RAW SQL查询是什么构建的,并将其与原始查询进行比较。

您可以使用以下查询:

->all()