Laravel Eloquent搜索异常:tahun_id筛选条件失效问题
问题根源
问题出在SQL逻辑运算符的优先级上。你当前的查询结构会被解析成:
WHERE tahun_id IN (...) AND no_proposal LIKE '%xxx%' OR uraian LIKE '%xxx%' OR ...
由于AND优先级高于OR,实际执行逻辑等价于:
WHERE (tahun_id IN (...) AND no_proposal LIKE '%xxx%') OR (uraian LIKE '%xxx%') OR (...)
这就导致只要任意一个OR后的搜索条件匹配,就会绕过tahun_id的筛选,自然出现筛选失效的情况。
修复方案
把所有搜索相关的OR条件用闭包包裹在一个where()里,确保tahun_id的筛选和整个搜索条件是AND关系,最终SQL结构会变成:
WHERE tahun_id IN (...) AND ( no_proposal LIKE '%xxx%' OR uraian LIKE '%xxx%' OR ... )
修改后的search方法代码:
public static function search($search, $tahunId) { // 初始化公共查询逻辑,避免重复代码 $query = static::query() ->with('kegiatan', 'opd', 'tahun') ->whereIn('tahun_id', $tahunId); if (!empty($search)) { // 用闭包包裹所有OR搜索条件,保证和tahun_id是AND关系 $query->where(function ($q) use ($search) { $q->where('no_proposal', 'like', '%'.$search.'%') ->orWhere('uraian', 'like', '%'.$search.'%') ->orWhere('tgl_disposisi', 'like', '%'.$search.'%') ->orWhere('nominal_disposisi', 'like', '%'.$search.'%') ->orWhere('penerima', 'like', '%'.$search.'%') ->orWhere('alamat', 'like', '%'.$search.'%') ->orWhere('status', 'like', '%'.$search.'%') ->orWhereHas('kegiatan', function ($subQ) use ($search) { $subQ->where('jenis_kegiatan', 'like', '%'.$search.'%'); }) ->orWhereHas('opd', function ($subQ) use ($search) { $subQ->where('nama_opd', 'like', '%'.$search.'%'); }) ->orWhereHas('tahun', function ($subQ) use ($search) { $subQ->where('tahun_anggaran', 'like', '%'.$search.'%') ->orWhere('tahapan', 'like', '%'.$search.'%') ->orWhere('deskripsi', 'like', '%'.$search.'%'); }); }); } return $query; }
额外优化说明
- 提取了重复的
with和whereIn逻辑,减少代码冗余 - 结构更清晰,后续新增/修改搜索条件时更易维护
内容的提问来源于stack exchange,提问作者Putra Edi Sujito
相关产品推荐
相关产品推荐

