我无法将原始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}',
答案 0 :(得分:1)
假设您的原始SQL查询正常运行,则可以使用ActiveRecord或Query Builder创建查询。
要在查询中使用MYSQL函数,必须使用\yii\db\Expresion
,而在构建查询时,应在查询结束时使用->createCommand()->rawSQL
,并用->one()
或{{1}代替},然后回显查询以查看RAW SQL查询是什么构建的,并将其与原始查询进行比较。
您可以使用以下查询:
->all()