はじめに
未経験でエンジニアになって間もないので、知識不足などあると思います。
何卒ご理解ください。
前提条件
たくさんの会合があって、それぞれに参加者がいる状況を想定して開発しています。
会合情報が書いてあるテーブル(ここではMeetingsテーブル
とします)
と
参加者情報が書いてあるテーブル(ここではParticipantsテーブル
とします)
があって
それぞれ Meetingsテーブルのid
と Participantsテーブルのmeeting_id
で結合している。
Participantsの情報の中に、status= 0:参加、1:不参加 という情報があり、
参加数だけ取ってきて表示したいとします。
$sub = Participant::select('participants.meeting_id',DB::raw('count(*) as cnt'))
->where('participants.status', '=', 0)
->groupby('patricipants.meeting_id');
$query = Meeting::select(
'meetings.id as id',
'meetings.name as name',
その他Meetingの情報
'entry_num.cnt'
)
->leftjoin(DB::raw('('.$sub->toSql().') as entry_num'),'meetings.id','entry_num.meeting_id');
としたところ、下記のエラーが・・・
SQLSTATE[HY000]: General error: 2031 No data supplied for parameters in prepared statement
select
count(*) as aggregate
from
`meetings`
left join (
select
`participants`.`meeting_id`,
count(*) as cnt
from
`participants`
where
`participants`.`status` = ?
group by
`participants`.`meeting_id`
) as entry_num on `meetings`.`id` = `entry_num`.`meeting_id`
ナンノコッチャわからない・・・
where
participants
.status
= ?
ってstatus=0って指定しているはずだけどな??
とりあえず片っ端からググる
toSql()ってなんだろうなと思ってググっていると
こちらの記事に出会いました。
https://codelikes.com/confirm-laravel-sql/#toc2
toSqlメソッドを呼ぶと、実際に実行するSQLがパラメータ箇所を「?」で伏せた状態で返ってきます。
なるほど、だから status = 0 が取れていなかったのか・・・
$sub = Participant::select('participants.meeting_id',DB::raw('count(*) as cnt'))
->where('participants.status', '=', 0)
->groupby('patricipants.meeting_id');
$subGetBindings = $subGetBindings = preg_replace_array('/\?/', $sub->getBindings(), $sub->toSql());
$query = Meeting::select(
'meetings.id as id',
'meetings.name as name',
その他Meetingの情報
'entry_num.cnt'
)
->leftjoin(DB::raw('('.$subGetBindings.') as entry_num'),'meetings.id','entry_num.meeting_id');
$subGetBindings = $subGetBindings = preg_replace_array('/\?/', $sub->getBindings(), $sub->toSql());
ここでLaravelで用意されているpreg_replace_arrayヘルパーを使用して置換することができます。
すると、キャンセル分を含めずに参加人数を取ってくることができました
忘れないようにメモとして残しておきます。