Я хочу составить список студентов, которые не платили в текущем месяце или никогда не платили. можно обойтись одним построителем запросов или красноречивой функцией? С приведенным ниже кодом я могу сделать прямо противоположное тому, что хочу:/
$indebted = DB::table('students')->where('students.active',1)
->leftJoin('payments', 'students.id', '=', 'payments.user_id')
->whereMonth('payments.created_at','=', $today->month)
->get();






Я не знаю, какое значение вы передаете здесь.
$today->month
Вместо этого $today->month вы должны указать здесь точный месяц
Пожалуйста, попробуйте это
$indebted = DB::table('students')->where('students.active',1)
->leftJoin('payments', 'students.id', '=', 'payments.user_id')
->whereMonth('payments.created_at','=', 06)
->get();
Вот идентификаторы студентов, которые произвели платежи в текущем месяце и году.
$payments= DB::table('payments')
->whereMonth('created_at',date('m'))
->whereYear('created_at', date('Y'))
->pluck('user_id')->all();
использовать whereNotIn('id',[идентификаторы студентов, совершивших платежи])
$students = DB::table('students')
->whereNotIn('id',$payments)
->get();
Вы можете использовать Raw SQL в такой ситуации. Я предполагаю, что вы используете базу данных mysql
$sql=SELECT * from students s LEFT JOIN payments p ON s.id=p.user_id
WHERE s.active=1 AND (p.created_at is NULL or MONTH(MAX(p.created_at) < MONTH(CURRENT_DATE())) )
$students = DB::connection('mysql')->select( DB::raw(" $sql"));
foreach($students as $aStudent){
...
....
}
вы можете получить студента, у которого нет платежей в этом месяце
$students = App\student::whereDoesntHave('payments', function (Builder $query) {
$query->whereMonth('payments.created_at',$today->month);
})->where('active',1)->get();
В зависимости от того, насколько большими будут ваши данные, использование этих «вспомогательных» функций не годится для оптимизации базы данных, если вы не индексируете свои данные должным образом. По сути, они оборачивают столбец даты вокруг функции, например, MONTH(payments.created_at) = '05' - это приведет к последовательному сканированию этого столбца, поскольку функция нестабильна. Чтобы оптимизировать это, вам нужно либо создать функциональные индексы «СОЗДАТЬ ИНДЕКС idx_blah ON Payments (month(created_at))», либо сделать диапазон дат «->whereBetween('payments.created_at', [$today->startOfMonth, $ Today->endOfMonth]) (при условии, что $today является датой по углероду)