MySql对于时间段交集的处理和通用实现方式(MyBatis-Plus)

server/2024/9/24 8:15:52/

问题:一般传统时间筛选是在[ 开始时间 → 结束时间 ]这个区间内的子集,也就是全包含查询方式,这种只会筛选一种情况。如果场景需要是开展一个活动,需要活动时间检索应该但凡包含就返回,也就是需要查询这个时间段有涉及的都需要筛选出来,即返回产生交集的数据

1.数据分析

上图是4 - 5月份中开展活动7种时间段,如果以V1的启止时间作为筛选条件,会遇到6种情况

V2:数据位于查询左侧,不产生交集

        V2结束时间 ≥ V1开始时间

V3:数据交集查询左侧区域,产生交集

        V1开始时间 ≤ V3结束时间 ≤ V1结束时间,

V4:数据位于查询的子集内,产生交集

        V4结束时间 ≥ V1结束时间,V4开始时间 ≤ V1开始时间

V5:数据交集查询右侧区域,产生交集

        V1开始时间 ≤ V5开始时间 ≤ V1结束时间

V6:数据位于查询右侧,不产生交集

        V1结束时间 ≤ V6开始时间

V7:数据的部分子集数据位于查询全集区域,产生交集

        V7开始时间 ≥ V1开始时间,V1结束时间 ≤ V7结束时间,

        这 6 种情况,产生交集的只有 4 种,也就是需要把这4种情况的时间段筛选出来,可以归纳为三类场景

查询时间以 [ startTime, endTime ] 作为筛选条件,开始时间和结束时间为某一个时间段的代称

  1. 全部包含(子集)和左边包含(V3、V4)startTime ≥ 结束时间  ≥ endTime
  2. 右边包含 (V5)startTime ≥ 开始时间  ≥ endTime
  3. 全部包含(被子集)(V7)开始时间 ≥ startTime,endTime  ≥ 结束时间

2.MySql查询尝试

创建一个活动表,补充活动开始时间和结束时间,并填充6种情况数据数据

CREATE TABLE `activity` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',`activity_start_time` datetime DEFAULT NULL COMMENT '活动开始时间',`activity_end_time` datetime DEFAULT NULL COMMENT '活动结束时间',PRIMARY KEY (`id`)
) ENGINE = InnoDB AUTO_INCREMENT = 0 DEFAULT CHARSET = utf8 COMMENT = '活动';

我们需要查询的时间段是 [ "2022-04-28 00:00:00" , "2022-05-04 00:00:00" ] 涉及的数据

SELECT * from activity where
# 全部包含(子集)和左边包含
("2022-04-28 00:00:00" <=activity_end_time and activity_end_time <="2022-05-04 00:00:00")
# 右边包含
or ("2022-04-28 00:00:00"<=activity_start_time and activity_start_time <="2022-05-04 00:00:00")
# 全部包含(被子集)
or (activity_start_time <= "2022-04-28 00:00:00" and "2022-05-04 00:00:00" <= activity_end_time)

3.通用方法

Mysql通用模板

SELECT * from activity where
# 全部包含(子集)和左边包含
("开始时间" <=activity_end_time and activity_end_time <="结束时间")
# 右边包含
or ("开始时间"<=activity_start_time and activity_start_time <="结束时间")
# 全部包含(被子集)
or (activity_start_time <= "开始时间" and "结束时间" <= activity_end_time)

 MyBatis-plus通用功能

    /*** 时间交集,与当前时间有交集筛选** @param beginColumn 指定开始列* @param endColumn   指定结束列* @param startTime   开始时间* @param endTime     结束时间* @param <T>         类型* @param <R>         列类型* @return*/public <T, R> Consumer<LambdaQueryWrapper<T>> timeIntersection(SFunction<T, R> beginColumn, SFunction<T, R> endColumn, Date startTime, Date endTime) {return wrapper -> {//全部包含(子集)和左边包含wrapper.and(x -> x.ge(endColumn, startTime).le(endColumn, endTime))//右边包含.or(x -> x.ge(beginColumn, startTime).le(beginColumn, endTime))//全部包含(被子集).or(x -> x.le(beginColumn, startTime).ge(endColumn, endTime));};}

使用方式

 @Testpublic void testTime() throws Exception{//数据准备SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");Date startTime =sdf.parse("2022-04-28 00:00:00");Date endTime =sdf.parse("2022-05-04 00:00:00");//使用方式LambdaQueryWrapper<Activity> queryWrapper = new LambdaQueryWrapper<Activity>().func(startTime != null && endTime != null, timeIntersection(Activity::getActivityStartTime, Activity::getActivityEndTime, startTime, startTime));}/*** 时间交集,与当前时间有交合条件** @param beginColumn 指定开始列* @param endColumn   指定结束列* @param beginTime   开始时间* @param endTime     结束时间* @param <T>         类型* @param <R>         列类型* @return*/public static  <T, R> Consumer<LambdaQueryWrapper<T>> timeIntersection(SFunction<T, R> beginColumn, SFunction<T, R> endColumn, Date beginTime, Date endTime) {return wrapper -> {//全部包含(子集)和左边包含wrapper.and(x -> x.ge(endColumn, beginTime).le(endColumn, endTime))//右边包含.or(x -> x.ge(beginColumn, beginTime).le(beginColumn, endTime))//全部包含(被子集).or(x -> x.le(beginColumn, beginTime).ge(endColumn, endTime));};}@Data@NoArgsConstructor@AllArgsConstructorpublic class Activity{/** 主键 */private Long id;/** 开始时间 */private Date activityStartTime;/** 结束时间 */private Date activityEndTime;}

 


http://www.ppmy.cn/server/15603.html

相关文章

Flink Graph演变

1.概述 Flink 集群中运行的 Job&#xff0c;最终归根到底&#xff1a;还是构建一个高效能分布式并行执行的DAG执行图。一个 Flink 流式作业从 Client 提交到 Flink 集群到最后执行&#xff0c;总共经历 4 种状态&#xff0c;总体来说&#xff1a;Flink中的执行图可分成四层&…

【Python】爬虫-基础入门

目录 一、什么是爬虫 二、爬虫的主要用途 三、学会爬虫需要掌握的技能 四、爬虫使用的语言 五、编写爬虫需要的库&#xff0c;以python为例 六、爬虫示例-python 示例一 示例二 示例三 一、什么是爬虫 爬虫&#xff0c;又称网络爬虫或网页爬虫&#xff0c;是一种用来自…

# 从浅入深 学习 SpringCloud 微服务架构(四)Ribbon

从浅入深 学习 SpringCloud 微服务架构&#xff08;四&#xff09;Ribbon 段子手168 一、ribbon 概述以及基于 ribbon 的远程调用。 1、ribbon 概述&#xff1a; Ribbon 是 Netflixfa 发布的一个负载均衡器,有助于控制 HTTP 和 TCP客户端行为。 在 SpringCloud 中 Eureka …

《数据结构与算法之美》读书笔记4(递归)

递归是一种应用非常广泛的算法。之后要讲的很多数据结构和算法的编码实现都要用到递归&#xff1a;DFS深度优先搜索&#xff0c;前中后序二叉树遍历等。 推荐注册返佣金这个功能&#xff0c;用户A推荐用户B来注册&#xff0c;用户B推荐用户C来注册。可以说用户B的“最终推荐人…

opencv 打开中文路径图报错

img cv.imread(中文图, 1) [ WARN:06.414] global D:\a\opencv-python\opencv-python\opencv\modules\imgcodecs\src\loadsave.cpp (239) cv::findDecoder imread_(‘D:/download/中文.png’): can’t open/read file: check file path/integrity 转换编码无法解决 file_pa…

后端程序员利用 AI 给网站制作专业 favicon

看看你的 Chrome 浏览器顶部的标签页&#xff0c;每个标签页前面有一个小小的图标&#xff0c;这个就是 favicon&#xff0c;如果你将网页保存到收藏夹&#xff0c;前面也会是这个小图标。这个图标有时候就是网站的 Logo&#xff0c;有时候也不太一样。 上面截图中&#xff0c…

记内网http洪水攻击,导致网页无法访问一事

事由 最近两日&#xff0c;部分同事在访问税纪云平台时&#xff0c;登录跳转页面频繁转圈、要么就是出现无法连接的错误提示。 无法访问此页面 已重置连接。 请尝试: 检查连接检查代理和防火墙运行 Windows 网络诊断经过以下几方面的排查&#xff0c;无果。 后续通过检查…

Footprint Analytics 与 GalaChain 达成战略合作

​ Footprint Analytics 宣布与 GalaChain 达成战略合作。GalaChain 是 Gala 旗下的 Layer 1 区块链。此次合作标志着双方在游戏&#xff08;包括 Gala Games) 、娱乐和金融等多个行业的区块链生态系统革新方面迈出了重要的一步。 GalaChain 致力于满足企业级项目的广泛需求&…