Laravelで内部結合してデータを取得するにはどうすればいいんだろう…
こんな疑問を解決します。
1つのテーブルだけでなく、複数のテーブルを結合してデータを取得したいって時ありますよね。
この記事では、shopsテーブルとmenusテーブルを例に内部結合でデータを取得する方法を解説します。
【動作環境】
Laravel8
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
Laravelで内部結合の事前準備で、テーブル作成&データを投入する
内部結合をする準備として、テーブルを作成しましょう。
ここで作成するテーブルはshops(店舗)テーブルとmenus(メニュー)テーブルです。
shopsテーブル
id | 店舗ID |
shop_name | 店舗名 |
menusテーブル
id | メニューID |
shop_id | 店舗ID |
menu_name | メニュー名 |
マイグレーションファイルを作成して、テーブルを作りましょう。
$ php artisan make:migration create_shops_table
shopsテーブルを作成
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateShopsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('shops', function (Blueprint $table) {
$table->id();
$table->string('shop_name', 255);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('shops');
}
}
$ php artisan migrate
menusのマイグレーションファイルを作成し、menusテーブルを作成します。
$ php artisan make:migration create_menus_table
menusテーブルを作成
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMenusTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('menus', function (Blueprint $table) {
$table->id();
// Laravel7系以上なら以下で外部キー設定できる
$table->foreignId('shop_id')->constrained();
$table->string('menu_name', 255);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('menus');
}
}
Laravel7系以上なら外部キーは上記のようにかけますが、もしLaravel6系以下であれば、Laravel6系の公式ドキュメント(外部キー制約)を参照してください。
$ php artisan migrate
shopsとmenusテーブルができたので、shopsテーブルとmenusテーブルにデータを入れておきます。
shopsテーブルにサンプルデータをインサート
INSERT INTO `shops`(`id`, `shop_name`, `created_at`, `updated_at`) VALUES
(1,'すき家','2022-03-01 12:00:00', null),
(2,'ピザーラ','2022-03-01 12:00:00', null),
(3,'ガスト','2022-03-01 12:00:00', null),
(4,'餃子の王将','2022-03-01 12:00:00', null),
(5,'魚民','2022-03-01 12:00:00', null);
menusテーブルにサンプルデータをインサート
INSERT INTO `menus`(`id`, `shop_id`, `menu_name`, `created_at`, `updated_at`) VALUES
(1,1,'牛丼','2022-03-02',null),
(2,1,'チーズ牛丼','2022-03-02',null),
(3,2,'よくばりクウォーター','2022-03-02',null),
(4,2,'マルゲリータ','2022-03-02',null),
(5,3,'ハンバーグ','2022-03-02',null),
(6,3,'カレー','2022-03-02',null),
(7,4,'餃子定食','2022-03-02',null),
(8,4,'チャーハン','2022-03-02',null),
(9,5,'焼き鳥','2022-03-02',null),
(10,5,'シーザーサラダ','2022-03-02',null);
準備ができたので、実際にLaravelで内部・外部結合してデータを取得してみましょう。
Laravelで内部結合してデータを取得する
内部結合は、2つのテーブルにある条件が一致するカラムをもとに1つのテーブルのようにデータを取得するやり方です。
例えば、shopsテーブルはidを持ち、menusテーブルはshop_idを持っています。このshops.idとmenus.shop_idの値が一致するもの同士でテーブルを合体させる手法です。
以下のように、menus.shop_idとshops.idの値が一致するカラムがあった場合、
内部結合することで、menusテーブルのデータだけでなく、shopsテーブルのデータもあわせて取得できます。
SQLで書くとこんな感じ。
SELECT
*
FROM
menus
INNER JOIN
shops
ON menus.shop_id = shops.id
;
Laravelのクエリビルダを用いて、内部結合を書くとこんな感じになります。
// 基本パターン
join('結合先テーブル', 'テーブル1.参照カラム', '=', 'テーブル2.参照カラム')
例)
$menus = Menu::join('shops', 'menus.shop_id', '=', 'shops.id')
->get();
// イコールは省略できます。
$menus = Menu::join('shops', 'menus.shop_id', 'shops.id')
->get();
dd($menus)でデバッグしてみると、以下のようにmenusのデータだけでなく、shopsテーブルのshop_nameもデータ取得できています。
もし2つ以上のテーブルを内部結合する場合は、joinを増やします。
$menus = Menu::join('shops', function($join) {
$join->on('menus.shop_id', 'shops.id');
})
->join('', function($join) {
$join->on('', '');
})
->get();
実務で書く場合は、内部結合の条件だけではなく、whereなどと組み合わせることがよくあります。
その場合は、join句の2番目の引数にクロージャを渡します。
// 基本パターン
$menus = Menu::join('結合先テーブル', function($join) {
$join->on('テーブル1.参照カラム', 'テーブル2.参照カラム')
})
例)
$menus = Menu::join('shops', function($join) {
$join->on('menus.shop_id', 'shops.id')
->where('shops.id', 3);
})
->get();
$join句のなかでも変数を使いたい場合があるでしょう。その場合はuseを使って変数を渡します。
$value = 'すき家';
$menus = Menu::join('shops', function($join) use ($value) {
$join->on('menus.shop_id', 'shops.id')
->where('shops.shop_name', $value);
})
->get();
shop_nameがすき家の条件で、内部結合したデータを取得できます。
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
コメント