Rumah > Soal Jawab > teks badan
Saya mempunyai pertanyaan SQL ini yang melakukan apa yang saya mahu:
SELECT `Table1`.* FROM `Table1` LEFT JOIN `Table2` ON `Table1`.`idTable2` = `Table2`.`id` WHERE (`Table1`.`idOwner`=156 AND `Table2`.`enabled`=1 AND day(Table2.creationDate) <= 5 AND date_format(Table2.creationDate, '%Y-%m') = '2022-12') OR (`Table1`.`idOwner`=156 AND `Table2`.`enabled`=1 AND date_format(Table2.creationDate, '%Y-%m') != '2023-01' AND date_format(Table2.creationDate, '%Y-%m') != '2022-12')
Saya cuba menyalinnya sebagai pembina pertanyaan Yii seperti ini:
Table1::find() ->joinWith(['table2']) ->where(['Table1.idOwner' => $idOwner, 'Table2.enabled' => 1]) ->andWhere(['<=', 'day(Table2.creationDate)', $expirationDay]) ->andWhere(['=', "date_format(Table2.creationDate, '%Y-%m')", $previousExpirationMonthYear]) ->orWhere(['Table1.idOwner' => $idOwner, 'Table2.enabled' => 1]) ->andWhere(['!=', "date_format(Table2.creationDate, '%Y-%m')", $currentExpirationMonthYear]) ->andWhere(['!=', "date_format(Table2.creationDate, '%Y-%m')", $previousExpirationMonthYear]) ->all();
Tetapi saya mencetak SQL yang dijana oleh pembina pertanyaan ini menggunakan getRawSql()
dan ia kembali dengan cara yang pelik ini:
SELECT `Table1`.* FROM `Table1` LEFT JOIN `Table2` ON `Table1`.`idTable2` = `Table2`.`id` WHERE (((((((`Table1`.`idOwner`=156) AND (`Table2`.`enabled`=1)) AND (day(Table2.creationDate) <= 5)) AND (date_format(Table2.creationDate, '%Y-%m') = '2022-12')) OR ((`Table1`.`idOwner`=156) AND (`Table2`.`enabled`=1))) AND (date_format(Table2.creationDate, '%Y-%m') != '2023-01')) AND (date_format(Table2.creationDate, '%Y-%m') != '2022-12')) AND (`Table1`.`idOwner`='156')
Maaf jika ini sukar dibaca.
Bolehkah sesiapa membantu saya membuat pembina pertanyaan seperti yang saya mahukan? Saya akan bersyukur
P粉5961919632024-04-02 19:22:21
Setiap kali anda menggunakan andWhere()
或 orWhere()
, pembina pertanyaan mengambil syarat sedia ada dan melakukan sesuatu seperti ini:
atau
Masing-masing.
Jadi jika anda menghadapi situasi yang rumit, cuba hubungi
orWhere(new condition 1) ->andWhere(new condition 2)
Anda akan dapat
Tetapi dalam kes anda, anda perlu mendapatkan sesuatu seperti:
Untuk mencapai hasil yang serupa, anda boleh membina keadaan kompleks pertama dengan cara yang sama, tetapi syarat kedua mesti dibina dalam satu panggilan orWhere()
. Atau untuk menjadikannya lebih mudah dibaca, anda boleh membina dua keadaan kompleks secara berasingan dalam satu panggilan:
Table1::find()
->joinWith(['table2'])
->where([
'AND',
['Table1.idOwner' => $idOwner, 'Table2.enabled' => 1],
['<=', 'day(Table2.creationDate)', $expirationDay],
['=', "date_format(Table2.creationDate, '%Y-%m')", $previousExpirationMonthYear]
])->orWhere([
'AND',
['Table1.idOwner' => $idOwner, 'Table2.enabled' => 1],
['!=', "date_format(Table2.creationDate, '%Y-%m')", $currentExpirationMonthYear],
['!=', "date_format(Table2.creationDate, '%Y-%m')", $previousExpirationMonthYear]
])->all();