質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

8622閲覧

Laravelで別々のDBのテーブルをjoinする方法

yoto009

総合スコア9

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

5クリップ

投稿2021/12/15 05:46

編集2021/12/15 07:37

前提・実現したいこと

お世話になっております!
題名のとおりですが、Laravelで別々のDBのテーブルをクリビルダでjoinする方法があれば教えていただきたいです!よろしくお願い致します!

# config/database.php 'connections' => [ .... 'mysql_1' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'hoge'), 'username' => env('DB_USERNAME', 'hoge'), 'password' => env('DB_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => true, 'engine' => null, ], 'mysql_2' => [ 'driver' => 'mysql', 'host' => env('DB_HOST_OTHER', '127.0.0.1'), 'port' => env('DB_PORT_OTHER', '3306'), 'database' => env('DB_DATABASE_OTHER', 'hoge'), 'username' => env('DB_USERNAME_OTHER', 'hoge'), 'password' => env('DB_PASSWORD_OTHER', ''), 'unix_socket' => env('DB_SOCKET_OTHER', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => true, 'engine' => null, ], ....

【mysql_1/users】

user_idname
1てすと1
2てすと2

【mysql_2/favorites】
|favorite_id|user_id|name|
|:--:|:--:|]--:|
|1|1|映画|
|2|2|読書|

※テーブル構造はとりあえずこのままで

試したこと

DB::table(DB::raw('mysql_1.users AS user')) ->join(DB::raw('mysql_2.favorites AS favorite'),'user.user_id','=','favorite.user_id')

補足情報(FW/ツールのバージョンなど)

Laravel 8.7
php 7.4

追加

DB::select( DB::raw(" select x.user_id, x.name, y.name as favorite from mysql_1.users as x left join mysql_2.favorites as y on x.user_id = y.user_id ") );

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2021/12/15 05:55

Laravelじゃなかったらできるんでしょうか。直接SQL書いたりとか。
yoto009

2021/12/15 07:35

生のsqlだとできるみたいです。 追加しましたがLaravelでも一応rawを使って書けるようですが毎回rawを使いたくはないです…
guest

回答1

0

ベストアンサー

以下の書き方でどうでしょうか?

php

1DB::connection('mysql_1') 2 ->table('users as user') 3 ->join('mysql_2.favorites as favorite', 'user.user_id', '=', 'favorite.user_id');

解説

  • Laravel は複数データベースを扱う際, PDO コネクションを別管理する設計思想
  • そのため, DB ファサードの実体,すなわち Connection インスタンス(PDO のラッパー)を取得する段階で参照先 DB を切り替え, JOIN 対象だけデータベース名まで完全修飾する構文を使う

Eloquent への応用

php

1class User extends Model 2{ 3 protected $connection = 'mysql_1'; 4 5 public function hasMany(): HasMany 6 { 7 return $this->hasMany(Favorite::class); 8 } 9}

php

1class Favorite extends Model 2{ 3 protected $primaryKey = 'favorite_id'; 4 protected $connection = 'mysql_2'; 5 6 public function user(): BelongsTo 7 { 8 return $this->belongsTo(User::class); 9 } 10}

Eloquent を使う場合,上記のように $connection プロパティの設定で透過的に対処できます。ラクなので個人的にはこれが一番好みです。

投稿2021/12/15 08:28

編集2021/12/15 08:40
mpyw

総合スコア5223

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yoto009

2021/12/15 10:06 編集

> mpyw様 ご回答ありがとうございます!ご提示頂いた方法で取得できました! ご丁寧に解説まで載せて頂きありがとうございます!ただ自分に理解力がなくていまいちピンと来なかったのでお聞きしたいのですが、connectinでベースのDBを指定して切り替え、別DBのテーブルjoinする場合は、何故connectionしなくてもDB名(database.phpのキー名がmysqlだったとしても)からテーブル名までを指定すろことで取得できるのでしょうか?
mpyw

2021/12/15 10:17

「Laravel が FROM 句でのエイリアシングを考慮していない」かな?と思って書いてみたんですが,ローカル環境で SQL 生成を試してみたら普通に正しい結果になっているように見えますね。これでしたら,どっちのコネクションを使ったとしても動くように見えてしまいますね… 「できない」と判断したときのエラーなどを教えていただけませんか?
yoto009

2021/12/15 14:13

変な質問をしてしまってすみません。できないと判断したわけではないので特にエラーがでたとかではないです。connectionした後にjoinではdb名からの指定で参照できるというのが?だったという感じですね。
mpyw

2021/12/15 14:22 編集

なるほど,でしたら元のコードでも問題はないように思います!但し, config/database.php で複数コネクションを定義する場合は回答のコードのように PDO 接続ごと切り替えて,SQL文中では「デフォルトのデータベース名」は省略するほうが自然なコードになるかな?と思いました mysql_1 が Laravel 全体でデフォルト接続に設定されていてかつそこのテーブルを起点にする場合は,::connection() の部分は省略していきなり ::table() から入って大丈夫です。デフォルトではない mysql_2 を起点にする場合のみ ::connection('mysql_2') から入る必要があります。
mpyw

2021/12/15 14:19

DB::table('mysql_1.users AS user')->join('mysql_2.favorites AS favorite', 'user.user_id', '=', 'favorite.user_id') ↑多分 DB::raw() なしでいけるんじゃないでしょうか? "... as ..." という書き方は Laravel がパースして適切に取り扱ってくれるはずですね
mpyw

2021/12/15 14:24 編集

>> connectionした後にjoinではdb名からの指定で参照できるというのが これに関しては,SQL レベルでそういう文法が定義されているから…が理由の1つと言えるでしょう。同じ MySQL システム上に複数のデータベースが存在している場合に限り,異なるデータベースを参照することができます。
yoto009

2021/12/15 14:36

なるほど!勉強になります!細かい解説ありがとうございます! この度はこちらの知識不足でお手を煩わせてしまい申し訳ありません!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問