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

AptimusTom 2023-06-07 22:00:05

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

 

 

...全文
95 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
雨夹雪 2023-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

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

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

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

炎同学要努力 2023-06-08
  • 打赏
  • 举报
回复

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

34,623

社区成员

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

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