Laravel:Eloquentで2つのテーブルの不一致を抽出する

Laravel:Eloquentで2つのテーブルの不一致を抽出する

Laravel:Eloquentで2つのテーブルの不一致を抽出する

私はもともとフレームワークを使わずPHPを書いていたので作成した自作システムを作るまでDBの抽出はSQLを直接書いていました。その為、自作システム作成初期に書いたコードは(Eloquentでの文が分からず)DB::と書き出したものがいくつかあります。でもこれ、Laravelの中だと処理が多少遅いようで現在Eloquentに書換をしています。

そんな中「不一致Queryが超楽じゃん!」との感想と「???」との感想と共にあった為、備忘録としてここに記載します。

超簡単な不一致QueryのEloquentコード【doesntHave】

ノーマルなSQLではこんな感じでしょう。

やっている事は次の通りです。

  1. tableAにtableBを見える形(Left Join)で結合する
  2. JoinしたのにtableBが関連づいていない(NULLである)tableAを抽出する
  3. 結果、tableBに存在しないtableAのレコードが取り出される

これが、なんとEloquentだと一発!

これは超楽。破壊力半端ない。

もうちょっと複雑に取得するなら【whereDoesntHave】

JOIN先のテーブルで抽出条件を付けいたい時があります。その時は【whereDosentHave】が重宝します。

お~~、これはSQL書くよりだいぶ楽です。

但し、予定と違う値が抽出されてしまうことがあり、少し悩みました。

抽出条件 whereNotNullがもう一つ絡むと何故か正しい値が取得できない。

何をしたかったかと言うと次の通りです。

  1. 商品ID(tableB.item_id)が存在する
  2. 店舗ID(tableB.shop_id)が空白
  3. tableB.number=1
  4. 1~3の条件を満たすレコードが無いtableAのリストを作成

上のEloquentでは何故か1~3をともに満たす条件ではなく【商品ID(tableB.item_id)が存在する】商品が抽出されてしまいました。これは次のように分けて書く事で改善しました。

whereNotNULLが orWhereNotNULLの様に扱われた点は謎です。が解決策を見つけたので良しとしましょう。

何よりもDB::よりも明らかに処理が早い!40万レコードあっても待つのは一瞬です。

まとめ

いやぁ~、Eloquentってすごい!