読者です 読者をやめる 読者になる 読者になる

CakePHPで関連テーブルを取得するSQLをカスタマイズ

アソシエーションを設定して、recursiveを指定すれば、自動的に関連テーブルを取得してくれるCakePHPですが、SQLの発行回数が増えていったりします。
明示的にLEFT OUTER JOINとか書いてSQLの発行回数を抑えたい!という場合、Modelの'finderQuery'を指定します。
UserモデルがReportをhasManyしていて、ユーザ毎のReport一覧を出す際にReportに対応するCustomerを取得したい場合、
自動的に取得するならUserモデルにはReportをこんな感じで指定。(更新日時降順の場合)

	var $hasMany = array(
			'Report' =>
				array('className' => 'Report',
						'foreignKey' => 'user_id',
						'order' => array('modified' => 'desc'),
						'counterQuery' => ''
				),

SQLを指定する場合、finderQueryを書き換えます。

       'finderQuery' => 'SELECT * FROM reports as Report 
             LEFT OUTER JOIN customers as Customer ON Report.customer_id=Customer.id 
             WHERE Report.user_id in ({$__cakeID__$}) ORDER BY Report.modified DESC',

{$__cakeID__$}が肝ですね。「=」でなく「in (...)」になっているのは、複数件を取得したとき(一覧など)はidひとつでなく複数が置き換わるためです。(例:「1,2,3」など)
本当にこのままのSQLを実行するので、ソート順やLIMITもSQL内に書かないと反映されませんし、pagination非対応です。(CakePHP1.1の場合。1.2は違うかも)