当前位置: 首页 > news >正文

开窗函数实践-实现两行记录之间计算时间差

一、需求背景

基于保密要求,不放原始表,新建测试表用来演示

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&#xff0…...

(十二)【Jmeter】线程(Threads(Users))之setUp 线程组

简述 操作路径如下: 作用:在正式测试开始前执行预加载或预热操作,为测试做准备。配置:设置预加载或预热操作的采样器、循环次数等参数。使用场景:确保在正式测试开始前应用程序已经达到稳定状态,减少测试结果的偏差。优点:提供预加载或预热操作,确保测试的准确性。缺…...

代码随想录算法训练营第二十五天|216.组合总和III,17.电话号码的字母组合

目录 216.组合总和II 17.电话号码的字母组合 216.组合总和II 如果把 组合问题理解了,本题就容易一些了。 题目链接/文章讲解:代码随想录 视频讲解:和组合问题有啥区别?回溯算法如何剪枝?| LeetCode:216.…...

c#创建安装windows服务

背景:最近在做设备数据对接采集时,遇到一些设备不是标准的Service-Client接口,导致采集的数据不够准确;比如设备如果中途开关机后,加工的数量就会从0开始重新计数,因此需要实时监控设备的数据,进行叠加处理;考略到工厂设备比较多,实时监听接口的数据为每秒3次,因此将…...

day52 ResNet18 CBAM

在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: ​onCreate()​​ ​调用时机​:Activity 首次创建时调用。​…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用

一、方案背景​ 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...

day36-多路IO复用

一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...

消息队列系统设计与实践全解析

文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...