条件 orWhere 使用 laravel 6 无效

condition orWhere using laravel 6 not work

我有两个表,salariespointages,它们之间的关系是 belongsTo/hasMany。我想 select soldpayer 列的总和 salarie_idchantier_id 的日期条件和条件。我想成为可选的,如果我选择 salarie_idchantier_id,我想给我选择 salarie_idchantier_idpointages 或两者。但就我而言,即使我选择 salarie_idchantier_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);

我怀疑您不熟悉 where/whereRaworWhere/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() method works with placeholders; use them. 2) Try to avoid using raw statements at all where possible. There are helper functions to do things like the date calculations you're doing. 3) Grouping your constraints 是通过将闭包传递给 where()/orWhere() 来完成的。 4) 对函数结果进行比较(就像您对 YEARMONTHDAY 函数所做的那样)效率非常低;该列实际上变成了未编入索引的文本列。

以下代码将生成与上述代码等效的查询,但使来自请求的检查成为可选的:

$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();

处使用回调
 $dbObj->where(function($query) use ($request) {
       $query->orWhere('column_1',$request->column_1);
       $query->orWhere('column_2',$request->column_2);
});