开窗函数实践-实现两行记录之间计算时间差
一、需求背景
基于保密要求,不放原始表,新建测试表用来演示
insert into TEST0221 (采血人, 采血时间, 条码号, 病人ID)
values ('张三', to_date('21-02-2024 12:00:00', 'dd-mm-yyyy hh24:mi:ss'), '2024001', '0001');insert into TEST0221 (采血人, 采血时间, 条码号, 病人ID)
values ('张三', to_date('21-02-2024 12:01:00', 'dd-mm-yyyy hh24:mi:ss'), '2024002', '0001');insert into TEST0221 (采血人, 采血时间, 条码号, 病人ID)
values ('张三', to_date('21-02-2024 12:02:00', 'dd-mm-yyyy hh24:mi:ss'), '2024003', '0001');insert into TEST0221 (采血人, 采血时间, 条码号, 病人ID)
values ('张三', to_date('21-02-2024 14:00:00', 'dd-mm-yyyy hh24:mi:ss'), '2024004', '0001');insert into TEST0221 (采血人, 采血时间, 条码号, 病人ID)
values ('李四', to_date('21-02-2024 12:05:00', 'dd-mm-yyyy hh24:mi:ss'), '2024005', '0002');insert into TEST0221 (采血人, 采血时间, 条码号, 病人ID)
values ('李四', to_date('21-02-2024 12:06:00', 'dd-mm-yyyy hh24:mi:ss'), '2024006', '0002');insert into TEST0221 (采血人, 采血时间, 条码号, 病人ID)
values ('李四', to_date('21-02-2024 12:07:00', 'dd-mm-yyyy hh24:mi:ss'), '2024007', '0002');insert into TEST0221 (采血人, 采血时间, 条码号, 病人ID)
values ('李四', to_date('21-02-2024 12:08:00', 'dd-mm-yyyy hh24:mi:ss'), '2024008', '0003');insert into TEST0221 (采血人, 采血时间, 条码号, 病人ID)
values ('李四', to_date('21-02-2024 12:09:00', 'dd-mm-yyyy hh24:mi:ss'), '2024009', '0003');insert into TEST0221 (采血人, 采血时间, 条码号, 病人ID)
values ('李四', to_date('21-02-2024 12:10:00', 'dd-mm-yyyy hh24:mi:ss'), '2024010', '0003');

最近工作上接到一个需求,统计采血工作量,按人员统计采血人次,本来很好统计,业务上一个人可能一次采血可能会采集多管,但是只能算作采血人员只采集了一次,那么就按人次来计算,而不是按试管来计算,sql语句如下:
select 采血人,count(distinct 病人ID) as 采血人次 from TEST0221
group by 采血人;

但是很快需求方提出问题,张三的工作量少了1个,因为虽然他只采集了这一个人,但是他最后一次采集与前一次相差了2小时左右,很明显不是一次采集完的,经过一番沟通,确定了统计口径为:如果同一个人的采集时间与上一次间隔超过了10分钟,那么就应该把这次也算作一次工作量。
这样统计思路很清晰,但是SQL语句好像不太好写,或许有其他方式,但最终决定尝试用开窗函数解决。
二、问题解决
为了便于自己理清思路,分步骤写出sql语句。
首先我需要知道同一个采样人对同一个患者,每次采样时间与上一次采样的间隔,也就是需要在两行数据之间做计算,把同一个患者同一个采样人上一次的采样时间获取到,那么使用开窗函数lead来实现。
LEAD函数和 LAG函数主要用于查询当前字段的上一个值或下一个值,若向上取值或向下取值没有数据的时候显示为NULL
- LEAD: 向后偏移
- LAG: 向前偏移
关于开窗函数网上资料很多,可以自行了解。
select t.采血人,t.采血时间,t.条码号,t.病人id, lead(采血时间, 1) OVER(partition by 采血人, 病人id ORDER BY 采血时间 desc) as 前一次采血时间,(t.采血时间 - lead(采血时间, 1)OVER(partition by 采血人, 病人id ORDER BY 采血时间 desc))*24*60 as 间隔分钟数from TEST0221 t;
此处解释下 lead(采血时间, 1) OVER(partition by 采血人, 病人id ORDER BY 采血时间 desc)
其中 lead(采血时间, 1) 的1是偏移量,采血时间是要取的字段
其中 partition by 采血人, 病人id 是在窗口中根据采血人和病人ID分组
ORDER BY 采血时间 desc 则是根据采血时间排序

到了这一步之后,思路就很清晰了,只需要在上面的基础上加上10分钟的判断并计数即可
select s.采血人,count(distinct s.计数项 ) as 采血人次 from (
select t.采血人,t.采血时间,t.条码号,case when (t.采血时间 - lead(采血时间, 1)OVER(partition by 采血人, 病人id ORDER BY 采血时间 desc))*24*60>10 then 病人id||'-'||to_char(采血时间,'yyyy-mm-dd hh24:mi:ss') else病人id end as 计数项from TEST0221 t) s group by s.采血人;

相关文章:
开窗函数实践-实现两行记录之间计算时间差
一、需求背景 基于保密要求,不放原始表,新建测试表用来演示 insert into TEST0221 (采血人, 采血时间, 条码号, 病人ID) values (张三, to_date(21-02-2024 12:00:00, dd-mm-yyyy hh24:mi:ss), 2024001, 0001);insert into TEST0221 (采血人, 采血时间…...
String字符串的常见方法总结
目录 一、int length():返回字符串的长度 二、char charAt(int index):返回某索引处的字符 三、boolean isEmpty():判断字符串是否为空 四、String toUpperCase():将字符转换成大写 五、String toLowerCase():将字符转换成小写 六、String trim():去除首尾空白…...
Postgresql源码(122)Listen / Notify与事务的联动机制
前言 Notify和Listen是Postgresql提供的不同会话间异步消息通信功能,例子: LISTEN virtual; NOTIFY virtual; Asynchronous notification "virtual" received from server process with PID 8448. NOTIFY virtual, This is the payload; Asy…...
QT 数据库的增加操作和画图 Win
第一步、先配置CMakeLists.txt 在CMakeLists.txt中添加 find_package(Qt6 REQUIRED COMPONENTS Sql) find_package(Qt6 REQUIRED COMPONENTS Charts)target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Sql) target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Charts)避…...
【JS逆向学习】同花顺(q.10jqka)补环境
逆向目标 目标网址:https://q.10jqka.com.cn/ 目标接口: https://q.10jqka.com.cn/index/index/board/all/field/zdf/order/desc/page/3/ajax/1/ 目标参数:cookie 逆向过程 老规矩,先分析网络请求,发现是 cookie 加…...
解决MobaXterm网络错误连接超时问题
报错页面: 报错原因: ①网络断开了 ②网络端口,端口号改变 解决办法: ①重新连接网络按R ②固定端口号 第一步:编辑------>虚拟机网络编辑器(我的Linux在虚拟机里) 第二步:用…...
突发!AI独角兽「竹间智能」被曝停工停产6个月
大家好我是二狗。 今天早上起来刷朋友圈,看到一张截图——AI创企竹间智能,宣称因为公司所处的经营环境艰难,部分部门和岗位将从即日起停工停产6个月。 图源:(企服科学) 下面是文字版: 由于公司…...
Qt应用软件【协议篇】GPIO控制LED灯
GPIO简介 GPIO(General Purpose Input/Output,通用输入输出)是一种通用的端口定义,在各种计算机、嵌入式系统和微控制器中广泛应用。通过GPIO,计算机或微控制器可以与外部世界进行交互,例如读取传感器数据或控制外部设备(如LED灯、电机等)。 GPIO的应用场景 按钮和开…...
vulfocus靶场搭建
vulfocus靶场搭建 什么是vulfocus搭建教程靶场配置场景靶场编排靶场优化 什么是vulfocus Vulfocus 是一个漏洞集成平台,将漏洞环境 docker 镜像,放入即可使用,开箱即用,我们可以通过搭建该靶场,简单方便地复现一些框架…...
Swift基础知识:30.Swift访问控制
在 Swift 中,访问控制(Access Control)是一种用于限制代码模块对其他代码模块的访问权限的机制。通过访问控制,可以控制代码中各个部分的可见性和可访问性,以便于提高代码的安全性、可维护性和可复用性。 访问级别 S…...
ElasticSearch聚合操作
目录 ElasticSearch聚合操作 基本语法 聚合的分类 后续示例数据 Metric Aggregation Bucket Aggregation ES聚合分析不精准原因分析 提高聚合精确度 ElasticSearch聚合操作 Elasticsearch除搜索以外,提供了针对ES 数据进行统计分析的功能。聚合(aggregation…...
普中51单片机学习(定时器和计数器)
定时器和计数器 51单片机有两组定时器/计数器,因为既可以定时,又可以计数,故称之为定时器/计数器。定时器/计数器和单片机的CPU是相互独立的。定时器/计数器工作的过程是自动完成的,不需要CPU的参与。51单片机中的定时器/计数器是…...
having子句
目录 having子句 having和where的区别 Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 现在要求查询出每个职位的名称,职位的平均工资,但是要求显示平均工资高于 200 的职位 按照职位先进行分组,同…...
STM32H7 系列 MCU 内部 SRAM
通过参看《STM32H7 参考手册》“2.4 Embedded SRAM”章节知道 The STM32H743/53xx and STM32H750xB 内存特性: Up to 864 Kbytes of System SRAM 128 Kbytes of data TCM RAM 64 Kbytes of instruction TCM RAM 4 Kbytes of backup SRAM 1.1 TCM SRAM TCM : Tightly-Coupled …...
备战蓝桥杯---动态规划(应用2(一些十分巧妙的优化dp的手段))
好久不见,甚是想念,最近一直在看过河这道题(感觉最近脑子有点宕机QAQ),现在算是有点懂了,打算记录下这道又爱又恨的题。(如有错误欢迎大佬帮忙指出) 话不多说,直接看题&…...
从 git 分支中合并特定文件,而不是整个分支的内容
问题 在git 中,我们可以使用 git merge 命令,合并整个分支,覆盖当前分支的内容,但是有时候我们并不想这么做,而是想 merge 某个文件。那么下面提供两种办法。 方法一 使用 git checkout,从别的分支&#x…...
pycharm 远程运行报错 Failed to prepare environment
什么也没动的情况下,远程连接后运行是没问题的,突然在运行时就运行不了了,解决方案 清理缓存: 有时候 PyCharm 的内部缓存可能出现问题,可以尝试清除缓存(File > Invalidate Caches / Restart࿰…...
(十二)【Jmeter】线程(Threads(Users))之setUp 线程组
简述 操作路径如下: 作用:在正式测试开始前执行预加载或预热操作,为测试做准备。配置:设置预加载或预热操作的采样器、循环次数等参数。使用场景:确保在正式测试开始前应用程序已经达到稳定状态,减少测试结果的偏差。优点:提供预加载或预热操作,确保测试的准确性。缺…...
代码随想录算法训练营第二十五天|216.组合总和III,17.电话号码的字母组合
目录 216.组合总和II 17.电话号码的字母组合 216.组合总和II 如果把 组合问题理解了,本题就容易一些了。 题目链接/文章讲解:代码随想录 视频讲解:和组合问题有啥区别?回溯算法如何剪枝?| LeetCode:216.…...
c#创建安装windows服务
背景:最近在做设备数据对接采集时,遇到一些设备不是标准的Service-Client接口,导致采集的数据不够准确;比如设备如果中途开关机后,加工的数量就会从0开始重新计数,因此需要实时监控设备的数据,进行叠加处理;考略到工厂设备比较多,实时监听接口的数据为每秒3次,因此将…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
