私は、タスクとテストというActiveRecordモデルを持っています。タスクにはいくつかのテスト(またはゼロ)が含まれている場合があります。 Task
モデルでYii2 - 最新のhasMany関係で検索
関係:
public function getTests(){
return $this->hasMany(Test::className(), ['task_num' => 'task_num']);
}
public function getLastTest(){
return $this->hasOne(Test::className(), ['task_num' => 'task_num'])->addOrderBy(['test_num' => SORT_DESC])->limit(1);
}
予想したように、私が好きな、lastTest
関係は動作しません。私はこの関係を検索する必要があります。私がテストを持っている3に等しいステータスを持つすべてのタスクをフィルタリングする必要があり、最新のものは等しくないステータスを持つ4
TaskSearch
モデル:SQLクエリーを結果の
public function search($params)
{
$query = Task::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 10,
],
]);
// standart search content
// ...
// ...
// TASK_COMPLETE is 3
// TEST_COMPLETE is 4
$query->andFilterWhere(['tbl_task.status' => TASK_COMPLETE]);
$query->joinWith(['lastTest' => function($q){
$q->where('tbl_test.status <> ' . TEST_COMPLETE);
}]);
return $dataProvider;
}
は次のとおりです。
SELECT `tbl_task`.*
FROM `tbl_task`
LEFT JOIN `tbl_test` ON `tbl_task`.`task_num` = `tbl_test`.`task_num`
WHERE (`tbl_task`.`status`=3) AND (tbl_test.status <> 4)
ORDER BY `task_num` DESC, `test_num` DESC
LIMIT 10
このクエリは、のすべてのタスクが少なくとも1つのテストのステータスが4と等しくないことを検出しますが、のタスクのみを検索する必要があります。最後のテストのステータスが4に等しくないまたはwテストなしで。
必要な関係を定義して検索方法を設定するにはどうすればよいですか?
編集:
試行錯誤を経由して、私は正しいSQLクエリを見つけました:
SELECT t1.*
FROM tbl_task t1
LEFT JOIN tbl_test t2 ON t1.task_num = t2.task_num
WHERE
(t1.status = 3) AND
(t2.status <> 4) AND
(t2.test_num = (SELECT MAX(t3.test_num) FROM tbl_test t3 LEFT JOIN tbl_task t4 ON t3.task_num = t4.task_num))
にはどうすればsearch
方法からこのクエリを作ることができますか?
編集2:私が間違っていた
は、このクエリはどちらか動作しません。
何も変更されていませんが、クエリはまったく同じです。 – Exerion
私の更新された回答を試してください – gmc
最後の行は、パラメータが配列でなければならないため、エラーが発生します。 $ query-> andFilterWhere(['<>'、 'lt.status'、TEST_COMPLETE])はエラーをクリアしますが、結果のクエリは 'SELECT' tbl_task'です。* FROM 'tbl_task' LEFT JOIN' tbl_test'' lt' (tbl_task'.status' = 3)AND( 'lt'.'status' <> 4)ORDER BY' task_num' DESC、 'test_num'は 'tbl_task'で' 「DESC LIMIT 10」 – Exerion