You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL查询需求:基于单表列类型计算时长差值总和

计算tblStaffLog表中基于LogType的时间差小时总和

看起来你需要统计员工操作日志里,对应操作类型的时间差总小时数对吧?结合你给出的tblStaffLog表结构,我整理了两种实用的MySQL查询方案,分别适配不同版本的MySQL:

方案1:用窗口函数(MySQL 8.0及以上适用)

如果你的MySQL是8.0或更高版本,用LEAD()窗口函数会非常方便——它能帮我们快速获取同一个用户下,按时间排序的下一条操作记录。假设你的LogType是类似IN(登录)和OUT(登出)这种成对的操作类型,直接用下面的查询:

SELECT 
    UserName,
    SUM(TIMESTAMPDIFF(HOUR, LogTime, NextLogTime)) AS TotalHours
FROM (
    SELECT 
        UserName,
        LogType,
        LogTime,
        -- 获取当前记录的下一条操作时间
        LEAD(LogTime) OVER (PARTITION BY UserName ORDER BY LogTime) AS NextLogTime,
        -- 获取下一条操作的类型
        LEAD(LogType) OVER (PARTITION BY UserName ORDER BY LogTime) AS NextLogType
    FROM tblStaffLog
) AS sub
-- 只筛选登录后紧跟登出的有效配对
WHERE LogType = 'IN' AND NextLogType = 'OUT'
GROUP BY UserName;

这个查询的逻辑很清晰:子查询先给每条记录匹配它的下一条操作记录,外层只保留登录和登出的有效配对,计算每对的时间差(转成小时),最后按用户求和总时长。

方案2:自连接(兼容MySQL 5.x等低版本)

如果你的MySQL版本不支持窗口函数,用自连接也能实现需求。我们需要把每个登录记录和它对应的最早登出记录关联起来,同时确保中间没有其他操作干扰:

SELECT 
    s1.UserName,
    SUM(TIMESTAMPDIFF(HOUR, s1.LogTime, s2.LogTime)) AS TotalHours
FROM tblStaffLog s1
JOIN tblStaffLog s2 
    ON s1.UserName = s2.UserName
    AND s2.LogType = 'OUT'
    AND s2.LogTime > s1.LogTime
    -- 确保两条记录之间没有其他登录/登出操作,保证是配对的
    AND NOT EXISTS (
        SELECT 1 FROM tblStaffLog s3
        WHERE s3.UserName = s1.UserName
        AND s3.LogTime BETWEEN s1.LogTime AND s2.LogTime
        AND s3.LogType IN ('IN', 'OUT')
        AND s3.SlNo NOT IN (s1.SlNo, s2.SlNo)
    )
WHERE s1.LogType = 'IN'
GROUP BY s1.UserName;

一些需要注意的细节

  • 记得根据你的实际业务调整LogType的取值(比如你的业务里可能是Login/Logout,不是IN/OUT)
  • 如果需要按其他维度统计(比如按PageName或Extension),只需要修改分组条件(窗口函数的PARTITION BY,或者自连接的关联条件)
  • 如果存在未配对的记录(比如只有登录没有登出,或者反之),上面的查询会自动忽略这些记录;如果需要处理这种情况,可以改成LEFT JOIN并对NULL值做特殊处理

内容的提问来源于stack exchange,提问作者Sudhakaran Packianathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:18:27