0

0

Laravel ORM:基于多列去除重复数据的高效方法

花韻仙語

花韻仙語

发布时间:2025-10-30 10:22:28

|

514人浏览过

|

来源于php中文网

原创

laravel orm:基于多列去除重复数据的高效方法

本文旨在解决在使用 Laravel ORM 时,如何基于多个列的值来移除重复记录的问题。通过使用 SQL 的窗口函数 `ROW_NUMBER()`,结合 Laravel 的 DB facade,提供了一种高效且易于理解的解决方案,避免了循环遍历和复杂的逻辑判断,并附带详细代码示例,帮助开发者快速实现该功能。

在使用 Laravel ORM 进行数据查询时,有时需要根据多个字段的值来判断记录是否重复,并只保留其中的一条。例如,在保存用户提交的比赛结果时,如果只更新分数,而不希望每次提交都创建一条新记录,就需要去除基于用户和各个科目的分数相同的重复记录,只保留最新的那一条。Laravel 提供的 distinct() 方法通常只能用于单个字段的去重,无法满足这种多列去重的需求。以下介绍一种使用 SQL 窗口函数结合 Laravel DB facade 实现多列去重的方案。

使用 SQL 窗口函数 ROW_NUMBER() 去重

核心思路是利用 SQL 的窗口函数 ROW_NUMBER() 为每个分组(基于需要去重的列)内的记录分配一个序号,然后只保留序号为 1 的记录。

ROW_NUMBER() OVER (PARTITION BY column1, column2, ... ORDER BY column_to_order DESC)

  • PARTITION BY column1, column2, ...: 指定分组的列,具有相同值的记录将被分到同一个组。
  • ORDER BY column_to_order DESC: 指定组内记录的排序方式,通常按照主键或时间戳倒序排列,以便保留最新的记录。

以下是一个 SQL 示例,假设我们有一个名为 results 的表,需要基于 username、discipline_one 到 discipline_six 这几个字段去重,并保留 id 最大的那条记录:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER
    (PARTITION BY username, discipline_one, discipline_two, discipline_three,
     discipline_four, discipline_five, discipline_six ORDER BY id DESC) rn
    FROM results
)

SELECT id, username, discipline_one, discipline_two, discipline_three,
     discipline_four, discipline_five, discipline_six, created_at, updated_at
FROM cte
WHERE rn = 1

这个SQL语句首先使用Common Table Expression (CTE) cte,计算每个分组内的行号,并将结果存储在名为 rn 的列中。然后,从 cte 中选择 rn = 1 的记录,即每个分组内的第一条记录,也就是最新的记录。

MVM mall 网上购物系统
MVM mall 网上购物系统

采用 php+mysql 数据库方式运行的强大网上商店系统,执行效率高速度快,支持多语言,模板和代码分离,轻松创建属于自己的个性化用户界面 v3.5更新: 1).进一步静态化了活动商品. 2).提供了一些重要UFT-8转换文件 3).修复了除了网银在线支付其它支付显示错误的问题. 4).修改了LOGO广告管理,增加LOGO链接后主页LOGO路径错误的问题 5).修改了公告无法发布的问题,可能是打压

下载

在 Laravel 中实现多列去重

为了在 Laravel 中使用上述 SQL 语句,可以借助 Laravel 的 DB facade,它允许直接执行原始 SQL 查询。

use Illuminate\Support\Facades\DB;

public static function waybackWhen($result)
{
    $username = $result->username;

    // 临时关闭 MySQL 严格模式 (可选,如果需要)
    config()->set('database.connections.mysql.strict', false);
    DB::reconnect(); // 重新连接数据库,使配置生效

    $resultSet = DB::select("
        WITH cte AS (
            SELECT *, ROW_NUMBER() OVER
            (PARTITION BY username, discipline_one, discipline_two, discipline_three,
             discipline_four, discipline_five, discipline_six ORDER BY id DESC) rn
            FROM results
        )

        SELECT id, username, discipline_one, discipline_two, discipline_three,
             discipline_four, discipline_five, discipline_six, created_at, updated_at
        FROM cte
        WHERE rn = 1 AND username = ?
   ", [ $username ]);

    // 恢复 MySQL 严格模式 (可选)
    config()->set('database.connections.mysql.strict', true);
    DB::reconnect();

    return $resultSet;
}

代码解释:

  1. DB::select(): 使用 DB facade 的 select() 方法执行 SQL 查询。
  2. SQL 查询: 使用上面提到的 SQL 语句,注意使用 ? 占位符来防止 SQL 注入。
  3. [ $username ]: 将 $username 变量作为参数传递给 SQL 查询,替换占位符。
  4. 严格模式: 如果MySQL开启了严格模式,执行此查询可能会报错。通过config()->set('database.connections.mysql.strict', false);可以临时关闭严格模式,并在查询完成后恢复。需要注意的是,修改配置后需要重新连接数据库才能生效。

使用示例:

$result = App\Models\Result::find(1); // 假设有一个 $result 对象
$waybackWhen = App\Models\Result::waybackWhen($result);

// $waybackWhen 现在包含了去重后的结果集
dd($waybackWhen);

注意事项

  • SQL 注入: 在使用 DB facade 执行原始 SQL 查询时,务必使用参数绑定(? 占位符)来防止 SQL 注入攻击。
  • 性能: 对于大数据量的表,使用窗口函数可能会影响性能。可以考虑添加合适的索引来优化查询。
  • 数据库兼容性: 不同的数据库系统对窗口函数的支持可能略有不同。请根据实际使用的数据库系统调整 SQL 语句。
  • 严格模式: 在MySQL严格模式下,如果SQL语句不符合严格模式的要求,可能会报错。需要根据实际情况选择是否临时关闭严格模式。

总结

本文介绍了一种基于 SQL 窗口函数和 Laravel DB facade 实现多列去重的方案。该方案简洁高效,避免了复杂的循环遍历和逻辑判断,能够有效地解决 Laravel ORM 在多列去重方面的不足。通过合理地使用 SQL 窗口函数,可以极大地简化数据处理逻辑,提高开发效率。

热门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,提供了直观易用的用户界面等等。

728

2023.10.12

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

1

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号