CakePHP 4.x: hasMany, belongsToMany でアソシエーションしたテーブルのレコードを contain で取得する際は、JOIN でなく、別のSQLで取得している

アソシエーションしたテーブルのレコードを contain して取得する際に実行される SQL は下記のように異なる

  • hasOne の場合は JOIN で取得
  • hasMany は別SQLで取得

追記

ドキュメント

hasOne の場合

class UsersTable extends Table
{
    public function initialize(array $config)
    {
        $this->hasOne('Addresses');
    }
}

$UsersTable->find('all')->contain(['Addresses']); を実行した場合は、JOIN で取得される。

SELECT * FROM users INNER JOIN addresses ON addresses.user_id = users.id;

hasMany の場合

class ArticlesTable extends Table
{
    public function initialize(array $config)
    {
        $this->hasMany('Comments');
    }
}

$ArticlesTable->find('all')->contain(['Comments']); を実行した場合は、別SQLで取得される。

SELECT * FROM articles;
SELECT * FROM comments WHERE article_id IN (1, 2, 3, 4, 5);

(※アソシエーションの設定で、'strategy' => 'subquery' を設定した場合は下記)

SELECT * FROM articles;
SELECT * FROM comments WHERE article_id IN (SELECT id FROM articles);