0

0

Laravel 查询条件:如何正确使用 AND 和 OR 实现复杂搜索逻辑

花韻仙語

花韻仙語

发布时间:2025-09-23 12:28:19

|

695人浏览过

|

来源于php中文网

原创

Laravel 查询条件:如何正确使用 AND 和 OR 实现复杂搜索逻辑

本文旨在解决 Laravel 查询中常见的 AND 和 OR 条件混淆问题,特别是在处理多字段模糊搜索时。通过分析 Laravel 查询构建器的行为,我们将重点介绍如何利用嵌套的 where 闭包来正确组合 AND 和 OR 逻辑,确保查询能够按照预期执行,从而实现更灵活、准确的数据检索,避免因条件组合错误导致数据遗漏。

1. 理解 Laravel 查询中的 AND 与 OR

laravel 的查询构建器中,当我们使用 where 方法并传入一个条件数组时,默认情况下,数组中的所有条件都会通过 and 逻辑进行组合。例如,以下 laravel 代码:

$entrys = t_e_elem::where([
    ['t_e_elem.fuse', '=', 1],
    ['t_entry.etitle', 'ilike', $title],
    ['t_entry.edesc','ilike',$title]
]);

会被 Laravel 转换为类似于这样的 SQL 语句:

SELECT * FROM `t_e_elems`
WHERE (`t_e_elem`.`fuse` = ? AND `t_entry`.`etitle` ILIKE ? AND `t_entry`.`edesc` ILIKE ?)

可以看到,t_entry.etitle 和 t_entry.edesc 两个条件之间也是 AND 关系。这意味着只有当 etitle 和 edesc 同时匹配 $title 时,记录才会被返回。这在许多搜索场景中并不符合预期,通常我们希望搜索条件是“标题包含 $title 或者 描述包含 $title”。

2. 正确实现 OR 逻辑:使用嵌套 where 闭包

为了在 Laravel 查询中实现 OR 逻辑,特别是当 OR 条件需要与其他 AND 条件组合时,我们需要使用嵌套的 where 闭包。这种方法允许我们创建一个独立的条件组,该组内部的条件可以按照 OR 逻辑进行组合,而整个组又会与外部的其他条件通过 AND 逻辑连接。

例如,如果我们的目标 SQL 是:

SELECT * FROM `users`
WHERE `t_e_elem`.`fuse` = ? AND (`t_entry`.`etitle` ILIKE ? OR `t_entry`.`edesc` ILIKE ?)

在 Laravel 中,可以通过以下方式实现:

燕雀Logo
燕雀Logo

为用户提供LOGO免费设计在线生成服务

下载
t_e_elem::where('t_e_elem.fuse', '=', 1)
    ->where(function ($query) use ($title) {
        $query->where('t_entry.etitle', 'ilike', $title)
              ->orWhere('t_entry.edesc', 'ilike', $title);
    });

在这个例子中:

  • where('t_e_elem.fuse', '=', 1) 是一个独立的 AND 条件。
  • where(function ($query) use ($title) { ... }) 创建了一个子查询(或称条件组)。
  • 在子查询内部,$query->where(...) 和 $query->orWhere(...) 实现了 etitle 和 edesc 之间的 OR 逻辑。
  • 最终,外部的 AND 条件会与整个 OR 条件组进行组合。

3. 将 OR 逻辑应用于复杂查询

现在,我们将上述 OR 逻辑集成到原始的复杂查询中,以正确地根据标题或描述进行数据筛选,并按省份统计。

orderBy('etext', 'ASC')->get();

        // 获取省份字段的form ID
        $formIdP = t_entry_form::where([['etype', 1], ['fname', 'field_province']])->first()->fid;

        foreach ($provinces as $province) {
            $entrysQuery = t_e_elem::selectRaw('t_entry.*, t_e_elem.*')
                ->join('t_entry', 't_e_elem.eid', '=', 't_entry.eid')
                ->join('t_e_value', 't_e_elem.fid', '=', 't_e_value.elid')
                ->join('t_entry_form', 't_e_value.fid', '=', 't_entry_form.fid')
                ->where('t_e_elem.fuse', '=', 1)
                ->where('t_entry.estatus', '1')
                // 核心改动:使用嵌套闭包实现标题或描述的OR搜索
                ->where(function ($query) use ($title) {
                    $query->where('t_entry.etitle', 'ilike', $title)
                          ->orWhere('t_entry.edesc', 'ilike', $title);
                })
                ->where([
                    ['t_e_value.fid', '=', $formIdP],
                    ['t_e_value.vvalue', '=', $province->eval],
                    // 注意:t_e_elem.fuse = 1 已经提前定义,这里如果重复且无特殊意义可移除
                    // 但为了保持原意,如果这里指代的是 t_e_value 相关的 fuse,则应明确
                    // 假设这里是冗余,因为 t_e_elem.fuse 已经在上面定义
                ]);

            // 使用 distinct 防止重复计数,并获取结果
            $entrys = $entrysQuery->distinct('t_entry.eid')->get();

            array_push($total, [
                'name' => $province->etext,
                'count' => count($entrys)
            ]);
        }

        return $total;
    }
}

代码解析与注意事项:

  1. 统一 OR 条件: 最重要的改动是将 ['t_entry.etitle', 'ilike', $title], ['t_entry.edesc','ilike',$title] 这两个条件从 where 数组中移除,并放入一个 where(function ($query) use ($title) { ... }) 闭包中,通过 orWhere 方法连接。
  2. 避免重复条件: 原始代码中在多个 where 子句中重复出现了 ['t_e_elem.fuse', '=', 1] 和 ['t_entry.etitle','ilike',$title], ['t_entry.edesc','ilike',$title]。在修改后的代码中,我们已经将 t_e_elem.fuse = 1 放在了查询链的早期,并且将 etitle 和 edesc 的 OR 条件统一处理。这样可以使查询更简洁、高效。
  3. distinct 的位置: distinct("t_entry.eid") 用于确保每个唯一的 t_entry.eid 只被计数一次,这对于避免因 join 操作可能引入的重复行非常重要。它应该在 get() 之前调用。
  4. ilike 操作符: ilike 是 PostgreSQL 特有的不区分大小写的模糊匹配操作符。如果使用的是 MySQL 或其他数据库,应使用 LIKE 配合 LOWER() 函数,或者在配置中设置不区分大小写排序规则。
  5. 模型引用: 示例代码中假设了 t_data_enum、t_e_elem、t_entry、t_e_value 和 t_entry_form 都是正确的 Eloquent 模型,并且已正确导入。

4. 总结

正确理解和使用 Laravel 查询构建器中的 AND 和 OR 逻辑是构建高效、准确查询的关键。当需要在一个查询中组合多种条件,尤其是涉及到多字段模糊搜索时,利用嵌套的 where 闭包是最佳实践。它不仅能确保生成的 SQL 语句符合预期,还能使代码结构更清晰、易于维护。始终检查生成的 SQL 语句(例如,通过 toSql() 方法或 Laravel Debugbar)是验证查询逻辑是否正确执行的有效手段。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
laravel组件介绍
laravel组件介绍

laravel 提供了丰富的组件,包括身份验证、模板引擎、缓存、命令行工具、数据库交互、对象关系映射器、事件处理、文件操作、电子邮件发送、队列管理和数据验证。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

320

2024.04.09

laravel中间件介绍
laravel中间件介绍

laravel 中间件分为五种类型:全局、路由、组、终止和自定。想了解更多laravel中间件的相关内容,可以阅读本专题下面的文章。

278

2024.04.09

laravel使用的设计模式有哪些
laravel使用的设计模式有哪些

laravel使用的设计模式有:1、单例模式;2、工厂方法模式;3、建造者模式;4、适配器模式;5、装饰器模式;6、策略模式;7、观察者模式。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

373

2024.04.09

thinkphp和laravel哪个简单
thinkphp和laravel哪个简单

对于初学者来说,laravel 的入门门槛较低,更易上手,原因包括:1. 更简单的安装和配置;2. 丰富的文档和社区支持;3. 简洁易懂的语法和 api;4. 平缓的学习曲线。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

374

2024.04.10

laravel入门教程
laravel入门教程

本专题整合了laravel入门教程,想了解更多详细内容,请阅读专题下面的文章。

85

2025.08.05

laravel实战教程
laravel实战教程

本专题整合了laravel实战教程,阅读专题下面的文章了解更多详细内容。

65

2025.08.05

laravel面试题
laravel面试题

本专题整合了laravel面试题相关内容,阅读专题下面的文章了解更多详细内容。

68

2025.08.05

数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

727

2023.10.12

Golang 网络安全与加密实战
Golang 网络安全与加密实战

本专题系统讲解 Golang 在网络安全与加密技术中的应用,包括对称加密与非对称加密(AES、RSA)、哈希与数字签名、JWT身份认证、SSL/TLS 安全通信、常见网络攻击防范(如SQL注入、XSS、CSRF)及其防护措施。通过实战案例,帮助学习者掌握 如何使用 Go 语言保障网络通信的安全性,保护用户数据与隐私。

2

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 2万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 812人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号