условие или где использование laravel 6 не работает - PullRequest
0 голосов
/ 25 марта 2020

У меня есть две таблицы, salaries и pointages, и между ними belongsTo / hasMany. Я хочу выбрать сумму столбцов sold и payer при условии даты и условия salarie_id и chantier_id. Я хочу быть необязательным, если я выберу salarie_id или chantier_id, я хочу дать мне либо pointages из salarie_id или chantier_id, либо оба. Но в моем случае, даже когда я выбрал salarie_id или chantier_id, он показал мне все строки.

$dataP = DB::table('salaries')
         ->join('pointages','pointages.salarie_id','salaries.id')
          ->selectRaw('SUM(pointages.sold) as sold,salaries.nom,salaries.prenom,salaries.id,SUM(pointages.payer) as payer')
          ->whereRaw(DB::raw('YEAR(pointages.datep) = ' .$request->annee))
          ->whereRaw(DB::raw('MONTH(pointages.datep) = ' .$request->mois))
          ->whereRaw( DB::raw('DAY(pointages.datep)>0 AND DAY(pointages.datep)<16')) 
          ->Orwhere('pointages.salarie_id','=',$request->salarie_id)
          ->OrWhere('pointages.chantier_id','=',$request->chantier_id)
          ->groupBy('pointages.salarie_id')
          ->get();
          return response($dataP);

Ответы [ 2 ]

1 голос
/ 25 марта 2020

Я подозреваю, что вы не знакомы с тем, как where / whereRaw и orWhere / orWhereRaw работают вместе.

В настоящее время ваше предложение WHERE выглядит следующим образом:

YEAR(pointages.datep) = ? and MONTH(pointages.datep) = ? and DAY(pointages.datep)>0 AND DAY(pointages.datep)<16 or `pointages`.`salarie_id` = ? or `pointages`.`chantier_id` = ?

Обратите внимание, что круглые скобки отсутствуют, означая, что любое из конечных условий может переопределить предыдущие. Вы можете легко определить, как будет выглядеть ваш запрос, используя методы построителя запросов toSql() или dd().

Мне кажется, вы ищете такой запрос?

SELECT SUM(pointages.sold) AS sold, SUM(pointages.payer) AS payer,
    salaries.nom, salaries.prenom, salaries.id
FROM salaries
LEFT JOIN pointages ON (pointages.salarie_id = salaries.id)
WHERE YEAR(pointages.datep) = ?
    AND MONTH(pointages.datep) = ?
    AND DAY(pointages.datep) > 0
    AND DAY(pointages.datep) < 16
    AND (
        pointages.salarie_id = ?
        OR pointages.chantier_id = ?
    )
GROUP BY pointages.salarie_id

Сначала пара замечаний: 1) не когда-либо помещайте необработанные данные в запрос SQL, как вы делали выше. whereRaw() метод работает с заполнителями; используй их. 2) Старайтесь по возможности избегать использования необработанных операторов. Есть вспомогательных функций для таких вещей, как вычисления даты, которые вы делаете. 3) Группировка ваших ограничений выполняется передачей замыкания в where() / orWhere(). 4) Выполнение сравнения с результатами функции (как вы делаете с вашими YEAR, MONTH и DAY функциями) очень неэффективно; столбец фактически становится столбцом неиндексированного текста.

Следующий код создаст запрос, эквивалентный приведенному выше, но делает проверки из запроса необязательными:

$dateStart = Carbon\Carbon::create($request->annee, $request->mois, 1, 0, 0, 0);
$dateEnd = $dateStart->addDays(15)->subSecond(1);

DB::table('salaries')
    ->leftJoin('pointages', 'pointages.salarie_id', 'salaries.id')
    ->select(['salaries.nom', 'salaries.prenom', 'salaries.id'])
    ->selectRaw('SUM(pointages.sold) AS sold')
    ->selectRaw('SUM(pointages.payer) AS payer')
    ->whereBetween('pointages.datep', [$dateStart, $dateEnd])
    ->where(function($q) use($request) {
        if ($request->has('salarie_id')) {
            $q->orWhere('pointages.salarie_id', $request->salarie_id);
        }
        if ($request->has('chantier_id')) {
            $q->orWhere('pointages.chantier_id', $request->chantier_id);
        }
    })
    ->groupBy('pointages.salarie_id')
    ->get();
0 голосов
/ 25 марта 2020

Использовать обратный вызов, где

 $dbObj->where(function($query) use ($request) {
       $query->orWhere('column_1',$request->column_1);
       $query->orWhere('column_2',$request->column_2);
});
...