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関数でバインド変数を指定することで回避します。