[Laravel] サブクエリをクエリビルダーで記述する方法

2022年4月6日

テクノロジー

eyecatch クエリビルダーって言葉をカッコイイと感じてしまう、ユゲタです。 Laravelって何でこんなに人気があるんでしょ? PHPの最新版でのみんなが寄ってたかって便利機能を詰め込んだフレームワークだからって認識で合ってますか? そんなLaravelの中でもModel機能におけるORMのクエリビルダーを使うと、paginator機能や、attribute機能や、いろいろな便利なデータベース連携機能を利用することができます。 通常のSQL文を単純に書き込んでいる状態では、この恩恵機能を受けることができません。 先日このブログで「PostgreSQLやOracleなどのファミリー関数をJOINで置き換える方法」というSQL文を作り出した記事を書いたんですが、このSQLをクエリビルダーで書いてみたいと思います。 SQL文は、ちょっと長いので、事前に先日のブログを見ておいてください。

コード作成

class Post extends Models { // 連載記事の一覧を取得 public static function getSymmaryDatas(){ $build = self::query(); $build->selectRaw(<<<_select_ posts.id post_id, posts.user_id post_user_id, posts.title post__title, posts.publish_date post__publish_date, summay.name summay_name, summay.name_e summay_name_e, summay.image summay_image _select_); $build->join('summary', function($join){ $join->on('posts.special_site_id', '=', 'summay.id') ->whereNotNull('summay.rensai_column_default_banner'); }); $now = Carbon::now(); $sub = DB::table('posts'); $sub->selectRaw(<<<_subSelect_ *, RANK() OVER ( PARTITION BY special_site_id ORDER BY publish_date DESC ) as rank _subSelect_) ->where('posts.status', '=', 1) ->where('posts.delete_flag', '=', 0) ->where('posts.publish_date', '<', $now) ->whereNotNull('posts.special_site_id'); $build->joinSub($sub, 'subQuery', function($join){ $join->on('subQuery.id', '=', 'posts.id') ->where('subQuery.rank', '=', 1); }); $build->orderBy('posts.publish_date', 'desc'); $build->get(); } }

解説

とりあえず、SQL文で変換しずらいところはそのままの文字列で、組み合わせ的な方法として変換してみました。 ポイントは、JOINが2つあるうちの1つは、サブクエリという方法を使っています。 「$sub」として、メインのSELECTであるテーブルと同じものをセットして、それをjoinSubしてrankの値を受け取っています。 ちなみに、$subは、DB::table()として、ビルダー化していますが、$sub = self::query();としてもらっても同じように動作します。

最後に

基本的には、SQLに忠実にビルダー化しているので、個人的には分かりやすくできたと思っていて、この記事は備忘録として書いているつもりです。 こうして人気のLaravelの機能を使っておくというのも、エンジニアとしては非常に重要な経験だと改めて感じてしまいました。 だって、今回の件で、分からない箇所をググってみたところ、Laravelの記事だらけで、ビックリしました。 おいおい、自分これ乗り遅れてるんじゃないか?と焦りすら感じてしまったので、とりあえずトレンドにしがみついている感じです。 まあ、自分が構築するシステムでは、Laravelなんて使わないですけどねwww。

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。