mysql左外联另一个表时关联字段是一对多,但只想要最新一条与之关联的优雅的解决方案

news/2025/1/24 9:17:11/文章来源:https://www.cnblogs.com/void--main/p/18689032

mysql左外联另一个表时关联字段是一对多,但只想要最新一条与之关联的优雅的解决方案

需求

  需求是这样:我们有表a为人员入场表,表b为人员登记表,但是我们有不能保证人员多次登记,所以这个时候我们只取最新的一条登记数据与入场表以人员id关联

历史解决方案(low的)

  按照以往的情况,我可能会把b表进行分组然后排序然后取第一条生成个表与第一个表关联,但是写法特别复杂类似这样:

SELECTa.*,v.*
FROMaLEFT JOIN (
SELECT b.*
FROM b b1
JOIN (SELECT user_id, MAX(create_time) AS max_timeFROM bGROUP BY user_id
) b2 ON b1.user_id = b2.user_id AND b1.create_time = b2.max_time;
) v on a.user_id = v.user_id

   而且极限情况如果create_time完全相同还会出现问题,

优雅解决方案(mysql 8.0以上)

  但是我最近发现个更优雅的写法

SELECTa.*,v.* 
FROMaLEFT JOIN (SELECT *, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY create_time DESC) AS rn FROM b) v ON a.user_id = v.user_id AND v.rn = 1

解释:

  PARTITION BY user_id:将结果集按 user_id字段进行分区。每个不同的 user_id 值会形成一个独立的分区。
  ORDER BY create_time DESC:在每个分区内部,按 create_time 字段降序排列。这意味着每个分区内的记录会根据 create_time 从最新到最旧进行排序。
  ROW_NUMBER():为每个分区内的记录分配一个行号,行号从1开始,按 create_time 的降序递增。

mysql5.7替代方案

  那有的同学说了我用的mysql5.7不支持窗口函数怎么办呢?没关系我们可以使用子查询和变量来模拟 ROW_NUMBER() 的行为

SELECTa.*,v.*
FROMaLEFT JOIN (SELECTb.*,@rn := IF(@current_user = user_id, @rn + 1, 1) AS rn,@current_user := user_idFROMb,(SELECT @rn := 0, @current_user := '') AS varsORDER BYuser_id, create_time DESC) v ON a.user_id = v.user_id AND v.rn = 1;
  1. 变量初始化:在子查询中,我们使用一个从 b 表和初始化变量的虚拟表 (SELECT @rn := 0, @current_user := '' AS vars) 的交叉连接。这允许我们在查询中初始化变量 @rn 和 @current_user

  2. 变量赋值:在 SELECT 子句中,我们使用 @rn 变量来存储每个 user_id 分组的行号。IF(@current_user = user_id, @rn + 1, 1) 这部分逻辑用于检查当前行是否与前一行有相同的 user_id。如果是,行号递增;如果不是,行号重置为 1。同时,@current_user := user_id 用于更新当前 user_id 的值。

  3. 排序:在 ORDER BY 子句中,我们按照 user_id 和 create_time DESC 对结果进行排序,以确保最新的记录具有行号 1。

  4. 外部查询:在外部查询中,我们执行一个左连接,将 a 表与我们的子查询结果 v 连接在一起,只选择每个 user_id 的最新记录(即 v.rn = 1)。

  5. 请注意,这种方法依赖于 MySQL 的变量和排序顺序,因此它的性能可能不如直接在支持窗口函数的 MySQL 版本中好。此外,如果表 b 非常大,这种方法可能会很慢,因为它需要对整个表进行排序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/874603.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

天通ERP S系列如何设置根据不同字段区分商品显示汇总,且在两个表中显示

展示效果:操作方式: 1、任我行打印管理器,点击右上角添加公式按钮,添加一个字段名称为空、字符类型为字符数据,且表达内容为空的公式字段保存(英文输入法下两个’’)2、在表头的最后添加一列,绑定刚才添加的空的公式字段,并绑定新增的字段为分单总计 且该字段取消显示边框 3、…

kettle从入门到精通 第九十一课 ETL之kettle http接口下载文件流

1、场景需求 群里一位老朋友想通过http接口下载文件流,然后将文件流保存为文件存储到本地,如下图所示: 2、做过应用程序研发,对http知识有所了解的,结合对方发的postman截图,一眼就知道了接口的真实面目。接口返回的content-type是application/octet-stream且有文件下载说…

搭建latex服务

1.领取免费服务器,推荐免费服务器(SanFengYun)见下图。2.安装宝塔面板,配置内网为127.0.0.1,访问外网地址。 3.可以在宝塔面板一键部署网站,输入自己的域名即可。 4.关键:安装docker,安装yum,设置github可以访问。 5.更换docker镜像,自带镜像无法访问 6.按照overleaf…

Cisco ASAv 9.22.1.3 - 思科自适应安全虚拟设备 (ASAv)

Cisco ASAv 9.22.1.3 - 思科自适应安全虚拟设备 (ASAv)Cisco ASAv 9.22.1.3 - 思科自适应安全虚拟设备 (ASAv) Cisco Adaptive Security Virtual Appliance (ASAv) 请访问原文链接:https://sysin.org/blog/cisco-asav/ 查看最新版。原创作品,转载请保留出处。 作者主页:sysi…

大文件跨国传输最优方案推荐,实现可靠稳定准确传输!

大文件跨国传输的需求广泛存在于多个行业中,这些行业对于数据的传输速度、安全性、稳定性和高效性都有着较高的要求。比如医疗机构在跨国医疗合作中需要传输医疗影像资料、诊断报告等;基建企业在海外的基础设施建设中,也包含数据出海环节,如通信运营商在海外建设网络时,需…

重拾 SSH:从基础到安全加固

安全外壳协议(Secure Shell Protocol,简称SSH)是一种加密的网络传输协议,属于应用层协议。OpenSSH 是最流行的 SSH 实现,它是大量操作系统的默认组件 OpenSSH 套件由以下工具组成:远程操作使用:ssh, scp 和 sftp 密钥管理:ssh-add, ssh-keysign, ssh-keyscan 和 ssh-ke…

史上第一位0:3夺得冠军

以颤抖之身追赶,怀敬畏之心挑战。--《棋魂》

【推荐】一款.NET Core开发的开源免费功能完善的医疗影像PACS系统

项目介绍 今天给大家推荐一款开源(MIT License开源协议)、免费、完善、轻量级的医疗影像PACS系统,基于.NET Core 的 DICOM SCP(Service Class Provider)服务器,提供 DICOM 存储、工作列表、查询检索服务,打印服务,WADO/DicomWeb服务,集成了功能强大的DICOM 桌面和Web查…

C# as 和 is 运算符区别和用法

前言 在C#中,as 和 is 关键字都用于处理类型转换的运算符,但它们有不同的用途和行为。本文我们将详细解释这两个运算符的区别和用法。 is 运算符 is 运算符用于检查对象是否是某个特定类型,或者是否可以转换为该类型。它返回一个布尔值 (true 或 false)。string title = &qu…

2025.1.24

树上背包DESTRUCTION 3,2,109 年论文现在才学也是没救了。 对于重量为 \(1\) 的,直接每次枚举 size 就可以做到 \(n^2\),证明考虑一个点对只会在 lca 出有一个贡献。 考虑重量是 \(v_i\),定义 \(v_i\) 的上界是 \(V\)。 暴力做是 \(nV^2\) 的,实在是不优美。 考虑更改更新顺…

读量子霸权13逆转衰老

热力学定律解释衰老,开放系统或可逆转。量子计算机或助解决衰老,实现生物与数字永生。热量限制、DNA修复、细胞重编程等或延长寿命,但需防副作用。1. 热力学第二定律 1.1. 热力学三大定律1.1.1. 第一定律简单地指出,物质和能量的总量是一个常数,能量不会从无到有,总是守恒…

更改暗盒DX码-DIY胶卷DX码

更改暗盒DX码-DIY胶卷DX码我们平时用纯机械相机可能更多一些,纯机械相机多数也不具备读取DX码这些信息的功能。有些傻瓜相机或自动相机需要读取这些信息,如果不能正确识别,有时候我们使用分装卷,暗盒都是二次利用的,因此DX码也是不正确的,机器读取出来就会造成曝光错误。…