SQLSERVER怎么求单表多行的不连续累积时间差?

AptimusTom 2023-06-07 22:00:05

在不使用游标的情况下,如何取得累计的间隔时长,重复的时间不计入 ,原始结构如图

 

 

...全文
84 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
雨夹雪 06-08
  • 打赏
  • 举报
回复 1
--不晓得对不对
--建表
CREATE TABLE #T
(
    id  INT IDENTITY(1,1) PRIMARY KEY,
    OperationName  VARCHAR(10),
    ModifiedOn DATETIME,
    OperationID VARCHAR(50),
    fz INT 
)

--插入数据
INSERT INTO #T(OperationName,ModifiedOn,OperationID) VALUES('进入','2023-06-01 03:00:38.000','2306010000000000377')
INSERT INTO #T(OperationName,ModifiedOn,OperationID) VALUES('进入','2023-06-01 03:00:43.000','2306010000000000378')
INSERT INTO #T(OperationName,ModifiedOn,OperationID) VALUES('进入','2023-06-01 03:00:49.000','2306010000000000379')

INSERT INTO #T(OperationName,ModifiedOn,OperationID) VALUES('退出','2023-06-01 07:26:22.000','2306010000000000379')
INSERT INTO #T(OperationName,ModifiedOn,OperationID) VALUES('退出','2023-06-01 07:26:22.000','2306010000000000378')
INSERT INTO #T(OperationName,ModifiedOn,OperationID) VALUES('退出','2023-06-01 07:28:03.000','2306010000000000377')


INSERT INTO #T(OperationName,ModifiedOn,OperationID) VALUES('进入','2023-06-01 07:41:21.000','2306010000000000854')
INSERT INTO #T(OperationName,ModifiedOn,OperationID) VALUES('进入','2023-06-01 07:41:26.000','2306010000000000855')
INSERT INTO #T(OperationName,ModifiedOn,OperationID) VALUES('进入','2023-06-01 07:41:30.000','2306010000000000856')

INSERT INTO #T(OperationName,ModifiedOn,OperationID) VALUES('退出','2023-06-01 08:39:18.000','2306010000000000854')
INSERT INTO #T(OperationName,ModifiedOn,OperationID) VALUES('退出','2023-06-01 08:39:18.000','2306010000000000855')
INSERT INTO #T(OperationName,ModifiedOn,OperationID) VALUES('退出','2023-06-01 08:39:18.000','2306010000000000856')

INSERT INTO #T(OperationName,ModifiedOn,OperationID) VALUES('进入','2023-06-01 12:31:53.000','2306010000000001495')
INSERT INTO #T(OperationName,ModifiedOn,OperationID) VALUES('退出','2023-06-01 12:40:15.000','2306010000000001495')

--更新分组,连续的,第一个进入到最后一个退出算一组
DECLARE @i INT =0,@OperationName VARCHAR(10)=''
UPDATE #T SET fz=@i ,@i=@i+IIF(@OperationName<>OperationName AND OperationName='进入',1,0), @OperationName=OperationName

SELECT *  FROM #T 

--统计
SELECT fz,DATEDIFF(mi, MIN(IIF(OperationName='进入',ModifiedOn,null)),MAX(IIF(OperationName='退出',ModifiedOn,null)) ) AS 分钟数
FROM #T 
GROUP BY fz
 
--删除
DROP TABLE #T

img

吉普赛的歌 版主 06-08
  • 打赏
  • 举报
回复

这种属于表没有设计好,给自己找麻烦。
userId loginTime logoutTime
3个字段就可以了。数据多的话还可以设计一个历史表,旧数据可以迁移到历史表。

按你这个,本身就有许多不正常的情况。
比如:有人有进入动作,但没有退出动作,后面的判断就非常麻烦。
你希望不用游标,那循环也是不想用吧,其实不容易做的了,吃力不讨好。
花点时间改下表结构吧

  • 打赏
  • 举报
回复

前面要有id吧,不可能是一个用户呀

Re:CCNA_CCNP 思科网络认证 动态路由 RIP 协议======================# RIP 协议中 network的作用 rip协议种network的应该怎么写 作用network 用来配置路由器:哪些接口参与到RIP协议中,功能如下: 接口能够发送和接收RIP数据包 该接口所在的网段会被RIP协议通告出去 方法:分析接口属于哪个网络(子网掩码默认,故需先分清A、B、C类地址) 多个接口属于同一个网段(按A、B、C分类),只需写一个。 # RIP协议工作过程 静态路由存在的问题 RIP协议工作特点 配置RIP协议 查看RIP协议学习到的路由 network的应该怎么写 查看运的RIP协议 查看RIP协议活动 RIPv1和RIPv2的区别 变长子网和等长子网 连续子网和不连续子网 RIPv2关闭自动汇总支持不连续子网 # 小型网络动态路由协议:RIP协议 路由信息协议RIP(Routing Information Protocol) 是一个真正的距离矢量路由选择协议。 它每隔30秒就送出自己完整的路由表到所有激活的接口。 建议终结端口可以关闭(#passive-interface fastEthernet 0/0) RIP协议选择最佳路径的标准就是跳数, 认为到达目标网络经过的路由器最少(跳数)的路径就是最佳路径。 暂时不以带宽为标准(后续...) 默认它所允许的最大跳数为15跳,也就是说16跳的距离将被认为是不可达的。 过期的路由信息被设置成16跳而非删除,原因为下次能够快速恢复 在小型网络中,RIP会运转良好, 但是对于使用慢速WAN连接的大型网络或者安装有大量路由器的网络来说, 它的效率就很低了。建议EIGRP和OSPF协议更适合 # rip 协议工作原理(图解) # 验证RIP协议健壮性 观察RIP协议更新路由信息的活动 # RIP协议默认会在网段类的边界自动汇总路由信息 不连续子网需要关闭RIP协议自动汇总功能 关闭RIP自动汇总的情况下:执手工精确汇总 # RIP 协议定时器# RIP阻止路由环路的方案------------------------------------              

34,498

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧