Edited at

cakePHP3のORMでexists句を使う。

More than 3 years have passed since last update.


cakePHP3のORMでexists句を使う。

cakePHP3でexists句を使うSQLを書こうと思ったところ、メソッドもないし、そもそも情報がない。

色々試した末、これで出来たかもと思われる方法をメモしたいと思います。

companyテーブル

id

name

employeeテーブル

id

company_id

name

deleted

の様なテーブルがあったとして、companyのid=1の社員を抽出したい場合(この場合existsを使わなくてもいいのですが、あえて使わせてください。)、SQLは、

select * from employee e where exists( select id from company c where e.company_id = c.id and c.id =1) and e.deleted = 0

これをCakePHP3のORMで記述すると

        $company= TableRegistry::get('company');

$subquery = $company->find()->where(['employee.id = id and id = :id'])->select(['id']);
$query->select(['employee.id', 'employee.name'])->Where("exists ({$subquery})")->Where(['employee.deleted' => 0])->bind(':id', 1);

と書けました。

bind関数を利用するところが肝で、サブクエリ内でbind関数を利用しない場合(配列で渡した場合)、SQLに変換した際、":c0"のバインド変数に変換され、外側のクエリで作成されるバインド変数":C0"と重複してしまいます。

これではまずいので、bind関数でバインド変数を指定することで回避します。