Laravel

LaravelでUnionを使って、違うテーブル同士を一緒に取得する方法

いつもご利用ありがとうございます。このブログは、広告費によって運営されています。

⇨ Laravel 記事の目次はこちら

Laravel で Union を使って、違うテーブル同士を一緒に取得する方法についてまとめました。違うテーブルというのは、例えば、posts テーブルと items テーブルのように、投稿と商品を同じ一覧に載せたい時などのケースがあげられます。

Union を使うケースを考える

例えば、ユーザーが記事と商品を投稿できるサービスがあるとして、それぞれ詳細ページがあるとします。

そこで、これら3つのテーブルをガッチャンコした上で

ユーザー
記事
商品

一覧化したいときに使えます。

他にも使う用途はおそらくあると思うので、もしあったらぜひ教えてください!

Union を使う方法

Union()を使う方法は至って簡単です。

コントーラーなどで、

  use App\Models\Item;
  use App\Models\Post;

~~~
public function index()
{
  $items = Item::select('title','created_at');
  $results = Post::select('title','created_at')
      ->union($items)
      ->get();
  dd($results);
}

こんな感じで書けば OK です。

union の()の中に、取得したい Eloquent を書いてあげるだけです。

where を使って検索する

タイトルのある item と post を取得する

例えばこうなります

$results = Post::select('title','created_at')
    ->union($items)
    ->whereNotNull('title')
    ->get();

全ての post とタイトルのある item を取得する

$items = Item::select('title','created_at')
  ->whereNotNull('title');
$results = Post::select('title','created_at')
    ->union($items)
    ->get();
dd($results);

このように、union の()の中で where してしまえば良いです。

世の中の union 記事、クエリビルダばかりしか引っかからないけど、Eloquent でもいけます。

Eloquent でもいけます。

なんやかんやリレーションが優秀なので、お世話になりたいですよね。

元となるテーブルのセレクトしたカラムの順番になる

union も万能ではありません。

元となるテーブルでセレクトしたカラムの順番になります。

そのため、union で入れたテーブルもそのカラムの順番で良いような select をしてあげる必要があります。

select でカラム数を合わせる必要がある

前述の特性があるため、union はカラム数を元となるテーブルに合わせる必要があります。

もし、もとのカラム数と違う数 select してしまった場合、

SQLSTATE[21000]: Cardinality violation: 1222 The used SELECT statements have a different number of columns (SQL: (select `title`, `created_at` from `posts` where `title` is not null) union (select `title` from `items`))

このようなエラーになります。

まとめ

以上です。

Laravel で Union を使う方法を記事にしました。

誰かの参考になればと思います。

感想・苦情は TwitterDM にご連絡ください。

それでは!

人気記事

PHP7.4 + Laravel6 のプロジェクトを AWS EC2 にデプロイする

【laravel-breadcrumbs】Laravel でパンくずリストを実装する