LaravelのクエリビルダでSELECT句にサブクエリを組み込む方法

やりたいこと:Left joinの中にサブクエリを挿入。

特に取得内容に意味はないけど、したいことはこんな感じのSQL。
LEFT JOINのwhere部分に値を埋め込む部分がどうしてもうまくいかなかった….

SELECT 
   name
FROM 
    TEST
LEFT JOIN(
   SELECT 
        id
   FROM 
        SCORS
   WHERE 
      day = '2022/09/01'
) as scora.id = Test.score_id

ダメなパターン:単純にサブクエリを読み込ませる。

$days = '2022/09/01';
$subQuery = SCORS::query()
            ->select([
                'id'
            ])
            ->where('day', $days)

$query = TEST::query()
           ->select([
                 'name'
             ])
           ->leftJoin(DB::raw('('. $subQuery->toSql() .') as scors'), 'scors.id', 'Test.score_id');

$query->get()

なことをやってたら、

<<Unknown error>>: 7 ERROR:  bind message supplies 1 parameters, but prepared statement.....

みたいな感じで怒られた。

サブクエリの中でバインドするのがダメなのかと諦めていたけど、、、、以下の方法で解決できた。

良いパターン:mergeBindingsメソッドを使って、サブクエリに値を読み込ませる!

$days = '2022/09/01';
$subQuery = SCORS::query()
            ->select([
                'id'
            ])
            ->where('day', $days)

$query = TEST::query()
           ->select([
                 'name'
             ])
           ->leftJoin(DB::raw('('. $subQuery->toSql() .') as scors'), 'scors.id', 'Test.score_id');

$query->mergeBindings($subQuery->getQuery())->get();

mergeBindingsメソッドを使うことで、

$subQueryで使う予定だった、バインド引数を本チャンクエリである$queryに渡すことができる。

いや~……ハマったorz

補足!順番に気をつけてね

バインディングする順番がよくズレることがあったので、getBindingsメソッドなどを使ってログ出力しながら実装するのがポイント!!


まとめ

まとめ

こちらのサイトには本当にお世話になりました。。

数回、素通りしてました。しっかり最初から読んでおけば、、、ありがとうございます!!

https://qiita.com/sato_ryu/items/1033fe51b886622a6dda

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です