例えばusersテーブルとpostsテーブルがあり、「users hasMany posts」としたとき、ユーザの投稿したメッセージ件数の一覧表など作りたいことなど、普通にあると思う。そんなとき、usersテーブルとposts テーブルをJOINして、同じuser_idを持つpostsデータをGROUP BYでまとめて、count()で件数を引っ張り出す。SQLで書くと以下のような感じ。
SELECT User.id,User.name,count(Post.user_id) AS num FROM users AS User LEFT JOIN posts AS Post ON User.id=Post.user_id GROUP BY User.id;
ここで、投稿を1度もしていないユーザを省略したい場合は、「LEFT JOIN」を「INNER JOIN」に変更すればよい。
さて、この自分が意図するSQLを、どのようにCakePHPを利用すれば、吐き出してくれるのだろうか?
以下のような方法で何とか解決したが、ちょっとトリッキーなやり方だな、と思う(ノ_-;)ハア…。
$this->User->unbindModel(array('hasMany'=>array('Post'))); $this->User->bindModel(array('belongsTo'=>array('Post'=>array( 'className'=>'Post', 'foreignKey'=>false, 'conditions'=>'User.id=Post.user_id', 'type'=>'inner', 'fields'=>array('count(Post.user_id) as num'))))); $users=$this->User->find('all', array('group'=>'User.id'));
ここでのミソは、
で、望みのSQLを吐き出してくれた。typeを省略すればLEFT JOINになるし、ユーザに条件を加えられるしで、なかなか使い勝手良いかも。modelに収めて隠ぺいすれば、controllerもスッキリ爽快気分になるに違いない(^o^)。
これと、group by句でposts.user_id指定したため、今日1日つぶした… orz。
以下、参考にしたサイトの記事です。ありがとうございました。
CakePHPのバージョンは、えーと、1.2.1_8004でした。