いつもの例を使いますと、商品productと商品画像product_imageの親子関係、つまり、1対多の関係があるとして、これに対して検索画面を作成するとします。
検索画面では、商品名だけでなく、商品画像のMIMEも検索項目として、検索できるようにします。つまり、親のテーブルの項目(商品名)でなく、子のテーブルの項目(MIME)も指定可能とします。
この場合、すぐに思いつくのは、以下のようにjoinして、その検索結果を表示です。
//検索値
$input[] = [
'name' => '商品名',
'mime' => 'image/gif'
];
$products = DB::table('product')
->join('product_image', 'product.product_id', '=', 'product_image.product_id')
->where('product.name', $input['name'])
->where('product_image.mime', $input['mime'])
->get();
しかし、これでは検索結果の各行は、商品画像のレコードとなってしまいます。1商品に対して、複数のGIF画像があるときは、複数分商品が表示されます。今回は、該当する商品のみを表示したいです。
となると、
$products = DB::table('product')
->join('product_image', 'product.product_id', '=', 'product_image.product_id')
->where('product.name', $input['name'])
->where('product_image.mime', $input['mime'])
->groupBy('product.product_id')
->get();
あるいは、joinでなくwhereInを使用して、
$products = DB::table('product')
->where('product.name', $input['name'])
->whereIn('product.product_id', function($query) use($input) {
$query->from('product_image')->select('product_id')->where('mime', $input['mime']);
})
->get();
$query->tableでなく、$query->fromというところがちょいとややこしいですね。しかし、親のレコードだけを引き出すという点では、joinを使用するよりわかりやすいです。
実効すると、このSQL文は以下のようになります。
select * from `product` where `name` = '商品名' and `product`.`product_id` in (select `product_id` from `product_image` where `mime` = 'image/gif')メルマガ購読の申し込みはこちらから。
