ライブラリと呼ばれるモデルを選択するために、Yii で複数のネストされた検索基準を使用しています。条件は次のとおりです。
$criteria = new CDbCriteria();
$criteria->select = 't.id, t.barcode_1_id, t.barcode_2_id, t.library_type_id, t.qc_pass';
$criteria->order = 'patient.id DESC, t.id DESC';
$criteria->together = true;
$with=array(
'isolates'=>array(
'select'=>false,
),
'samples'=>array(
'select'=>'samples.id, samples.sample_preservation_id, samples.tumor',
),
'patient'=>array(
'select'=>'patient.id',
),
'flowcells'=>array(
'select'=>'flowcells.id,flowcells.serial_id',
),
'libraryType'=>array(
'select'=>'libraryType.id,libraryType.short_name',
),
'samplePreservation'=>array(
'select'=>'samplePreservation.name',
),
'program'=>array(
'select'=>false,
'condition'=>'program.name NOT LIKE "%Lab%"',
),
'runs'=>array(
'select'=>'runs.id',
)
);
// by run ID
if (is_array($runs) && (! empty($runs))) {
$runCriteria = new CDbCriteria();
$runCriteria->addInCondition("runs.id", $runs, 'OR');
$criteria->mergeWith($runCriteria, $operator='OR');
$something=true;
}
// libraries without patients
if ( ($patients=='Unassigned') || (is_array($patients) && in_array('Unassigned',$patients)) ) {
$unassCriteria = new CDbCriteria();
$unassCriteria->addCondition('patient.id IS NULL');
$criteria->mergeWith($unassCriteria, $operator='OR');
$something=true;
}
if ( ($patients=='QC Pass') || (is_array($patients) && in_array('QC Pass',$patients)) ) {
$qcCriteria = new CDbCriteria();
$qcCriteria->addCondition('t.qc_pass = 1',$operator='AND');
$qcCriteria->addCondition('t.created BETWEEN CURDATE() - INTERVAL 30 DAY AND SYSDATE()','AND');
$criteria->mergeWith($qcCriteria, $operator='OR');
$something=true;
}
if ( ($patients=='Ready for Flowcell') || (is_array($patients) && in_array('Ready for Flowcell',$patients)) ) {
$readyCriteria = new CDbCriteria();
$readyCriteria->addCondition('flowcells.id IS NULL',$operator='AND');
$readyCriteria->addCondition('runs.current_pipeline_node_id = 7',$operator='AND');
$criteria->mergeWith($readyCriteria, $operator='OR');
$something=true;
}
if (is_array($patients) && (! empty($patients))) {
$ptArr= array_diff($patients, array('QC Pass','Unassigned','Ready for Flowcell'));
$ptCriteria = new CDbCriteria();
$ptCriteria->addInCondition("patient.id", $ptArr,$operator='OR');
if ($ptArr) $criteria->mergeWith($ptCriteria, $operator='OR');
$something=true;
}
if ($something) $librariesModel=Libraries::model()->with($with)->findAll($criteria);
次に、これらの結果をビュー用にフォーマットします。
問題は、Yii が $operator='OR' を無視し、常に OR の代わりに AND を使用していることです。これが生成する WHERE 句は次のとおりです。
(SELECT と JOIN は問題ないように見えます)
...
WHERE
(
(
( (patient.id IS NULL) AND ( (t.qc_pass = 1) AND (t.created BETWEEN CURDATE() - INTERVAL 30 DAY AND SYSDATE()) ) )
AND ( (flowcells.id IS NULL) AND (runs.current_pipeline_node_id = 7) )
)
AND (patient.id IN (:ycp0, :ycp1))
)
AND (program.name NOT LIKE "%Lab%")
ORDER BY patient.id DESC, t.id DESC, inventory_id ASC
Yii が「OR」を使用してこれらの基準をマージさせない理由は何ですか? 私の目標は、AND を含むが排他的ではないいくつかの括弧式を持つことです。mergeWith メソッドは、AND ではなく OR を使用して、これらの条件を WHERE 句に追加する必要があります。
ありがとう!