MySQL - 时间戳之间的平均差异,不包括周末和非工作时间

2023-12-06

我正在寻找能够平均时间戳之间差异的能力,排除周末和排除非工作时间(仅在 08:00:00 - 17:00:00 之间)。

我试图仅使用查询来实现此功能,但如果无法使用 MySQL,则可以回退到 PHP 函数

下面是我当前用来获取平均时间戳差异的函数。

例如。下面的查询将返回周五上午 8 点到周一下午 5 点之间的差异 81 小时,它需要返回 18 小时,因为它应该排除周末和工作日的非办公时间。

SQLFIDLE链接

SELECT 
    clients.name, 
    avg(TIMESTAMPDIFF(HOUR, jobs.time_created, jobs.time_updated)) AS average_response, 
    avg(TIMESTAMPDIFF(HOUR, jobs.time_created, jobs.time_closed)) AS average_closure, 
    count(jobs.id) AS ticket_count, 
    SUM(time_total) AS time_spent 
FROM 
    jobs
LEFT JOIN 
    clients ON jobs.client = clients.id 
WHERE 
    jobs.status = 'closed' 
GROUP BY 
    jobs.client

我看过在其他问题上但它们似乎不适用于时间戳中的小时,仅适用于日期。

Result

我现在正在使用下面的存储函数来实现我想要的结果。它将忽略工作时间以外的时间(08:00:00 - 17:00:00)并忽略周末。它本质上只会计算两个时间戳之间的营业时间差异。

DROP FUNCTION IF EXISTS BUSINESSHOURSDIFF;
DELIMITER $$
CREATE FUNCTION BUSINESSHOURSDIFF(start_time TIMESTAMP, end_time TIMESTAMP)
RETURNS INT UNSIGNED
BEGIN
IF HOUR(start_time) > 17 THEN SET start_time = CONCAT_WS(' ', DATE(start_time), '17:00:00');
END IF;
IF HOUR(start_time) < 8 THEN SET start_time = CONCAT_WS(' ', DATE(start_time), '08:00:00');
END IF;
IF HOUR(end_time) > 17 THEN SET end_time = CONCAT_WS(' ', DATE(end_time), '17:00:00');
END IF;
IF HOUR(end_time) < 8 THEN SET end_time = CONCAT_WS(' ', DATE(end_time), '08:00:00');
END IF;
RETURN 45 * (DATEDIFF(end_time, start_time) DIV 7) + 
          9 * MID('0123455501234445012333450122234501101234000123450', 
                  7 * WEEKDAY(start_time) + WEEKDAY(end_time) + 1, 1) + 
          TIMESTAMPDIFF(HOUR, DATE(end_time), end_time) - 
          TIMESTAMPDIFF(HOUR, DATE(start_time), start_time);
END $$
DELIMITER ;

这是可能的,但仅使用 sql 非常非常难看。但是,如果您可以使用存储函数,那么看起来也很漂亮。

从您在问题中链接的SO问题中,我们知道以下表达式计算两个日期之间的工作日数:

5 * (DATEDIFF(@E, @S) DIV 7) + 
    MID('0123455501234445012333450122234501101234000123450', 
        7 * WEEKDAY(@S) + WEEKDAY(@E) + 1, 1)

如果我们将此表达式乘以 9,即每个工作日的工作小时数,我们会得到business hours diff。添加两个时间戳之间的小时调整可以得到最终的表达式,然后我们可以对其进行平均

45 * (DATEDIFF(@E, @S) DIV 7) + 
      9 * MID('0123455501234445012333450122234501101234000123450', 
              7 * WEEKDAY(@S) + WEEKDAY(@E) + 1, 1) + 
      TIMESTAMPDIFF(HOUR, DATE(@E), @E) - 
      TIMESTAMPDIFF(HOUR, DATE(@S), @S)

所以,丑陋但有效的查询是:

SELECT 
  clients.name
, AVG(45 * (DATEDIFF(jobs.time_updated, jobs.time_created) DIV 7) + 
          9 * MID('0123455501234445012333450122234501101234000123450', 
                  7 * WEEKDAY(jobs.time_created) + WEEKDAY(jobs.time_updated) + 1, 1) + 
          TIMESTAMPDIFF(HOUR, DATE(jobs.time_updated), jobs.time_updated) - 
          TIMESTAMPDIFF(HOUR, DATE(jobs.time_created), jobs.time_created)) AS average_response
, AVG(45 * (DATEDIFF(jobs.time_closed, jobs.time_created) DIV 7) + 
          9 * MID('0123455501234445012333450122234501101234000123450', 
                  7 * WEEKDAY(jobs.time_created) + WEEKDAY(jobs.time_closed) + 1, 1) + 
          TIMESTAMPDIFF(HOUR, DATE(jobs.time_closed), jobs.time_closed) - 
          TIMESTAMPDIFF(HOUR, DATE(jobs.time_created), jobs.time_created)) AS average_closure
, COUNT(jobs.id) AS ticket_count 
, SUM(time_total) AS time_spent 
FROM jobs
LEFT JOIN clients ON jobs.client = clients.id 
WHERE jobs.status = 'closed' 
GROUP BY jobs.client

更好的选择是创建一个存储函数来处理business hours diff logic.

DROP FUNCTION IF EXISTS BUSINESSHOURSDIFF;
DELIMITER $$    
CREATE FUNCTION BUSINESSHOURSDIFF(start_time TIMESTAMP, end_time TIMESTAMP) 
RETURNS INT UNSIGNED
BEGIN
RETURN 45 * (DATEDIFF(end_time, start_time) DIV 7) + 
          9 * MID('0123455501234445012333450122234501101234000123450', 
                  7 * WEEKDAY(start_time) + WEEKDAY(end_time) + 1, 1) + 
          TIMESTAMPDIFF(HOUR, DATE(end_time), end_time) - 
          TIMESTAMPDIFF(HOUR, DATE(start_time), start_time);
END $$
DELIMITER ;

然后根据需要调用它。

SELECT 
    clients.name
  , avg(BUSINESSHOURSDIFF(jobs.time_created, jobs.time_updated)) AS average_response
  , avg(BUSINESSHOURSDIFF(jobs.time_created, jobs.time_closed)) AS average_closure
  , count(jobs.id) AS ticket_count
  , SUM(time_total) AS time_spent 
FROM jobs
LEFT JOIN clients ON jobs.client = clients.id 
WHERE jobs.status = 'closed' 
GROUP BY jobs.client;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySQL - 时间戳之间的平均差异,不包括周末和非工作时间 的相关文章

随机推荐

  • PHP,一个奇怪的变量范围?

    这更多的是一个关于 为什么 然后 如何做 的问题 但它已经困扰我好几天了 目前 我正在使用 CodeIgniter 进行一些工作 并暂时从 Ruby 返回到 PHP 这让我对以下作用域魔法感到困扰
  • 使用可重用图表更新 d3.js 中的 HTML 表格

    我有这个可重复使用的模式来创建一张桌子 灵感来自http bl ocks org 3687826 我对此有两个问题 这是函数 d3 table function config var columns var tbl function sel
  • ggplotly 从单个方面删除数据

    我正在尝试为闪亮的应用程序创建一个绘图 我遇到了有关多面图的某些布局的问题 每当有四个小平面并且它们位于 2x2 网格中时 左下小平面不会显示任何数据 即使数据存在于ggplot数字 当 3x2 网格中有 6 个面且左下角再次被丢弃时 也会
  • 类型同义词与类型类约束是否可能?

    请随意更改标题 我只是经验不足 不知道到底发生了什么 所以 我正在松散地编写一个程序this 并写下了这个 与原文一样 type Row a a type Matrix a Row a 那里没什么特别的 然而 我发现自己编写了几个具有如下类
  • 在宏运行结束时打开 NUMLOCK

    什么代码的作用 我有一个代码可以在屏幕上移动鼠标 打印屏幕并将其粘贴到 Excel 中 Problem 由于某种原因 我的代码总是 绝对没有例外 在每次运行后关闭 NUMLOCK 键 到目前为止我尝试过的 我四处搜寻 发现了 SendKey
  • 查询为空 PHP 错误

    我正在尝试使用 MySQL 构建一个购物车 当我运行此代码时 我不断收到此错误 查询为空 请帮助我尝试了几种方法 例如将变量放入字符串中而不是连接它
  • HTML 链接不会转到外部网站

    我在构建网站时一直使用react js运行本地主机网站 当我尝试链接到外部网站 例如youtube 时 它最终会转到如下链接 http localhost 3000 www youtube com 当我试图去时 https www yout
  • 我可以立即打印循环中的每次迭代吗?

    我的部署服务器为每个新的数据库构建运行一个部署脚本 部分脚本会阻塞以等待另一个异步操作完成 阻塞代码如下所示 DECLARE i INT 0 DECLARE laststatus NVARCHAR MAX N WHILE i lt 5 BE
  • cusparse csrsv_analysis 的性能非常慢

    我编写了一个带有 LU 预处理的共轭梯度求解器 用于线性方程组 我使用了 Maxim Naumov 博士的papers以nvidia的研究社区为指导 残差更新步骤需要先求解下三角矩阵系统 然后求解上三角矩阵系统 分为两个阶段 分析阶段 利用
  • 选择工资高于其部门平均水平的每位员工

    我只有 1 个名为EMPLOYEE在我的数据库中包含以下 3 列 Employee Name Employee Salary Department ID 现在我必须选择每个工资高于其部门平均水平的员工 我怎么做 我遇到的主要问题是 当将每个
  • 错误:只能在初始化程序中访问静态成员,这是什么意思?

    我有这样的东西 我很难理解这个错误 为什么访问filterController这里给出这个错误 但是如果我移动当前的整个内容 它不会给出这个错误TextFormField在构建方法中创建 在注释 A 和 B 之间 整个搬家如何TextFor
  • 从 MVC 的 DependencyResolver 转换到 AutofacWebApiDependencyResolver - .Current 在哪里?

    我让 AutoFac 与 MVC4 一起正常工作 我正在尝试过渡到 Web API 2 以下是我设置 AutoFac 的方法 public class AutofacRegistrations public static void Regi
  • Python 2.5 上选择模块的问题

    我有一个 Python 2 5 中的应用程序 用于监听 beanstalk 队列 到目前为止 除了我新买的 MacBook Pro 之外 它在我测试过的所有机器上都运行良好 在那台计算机上 当我尝试运行它时 出现以下错误 Traceback
  • 如何从使用 LINQ to SQL 的方法返回查询结果

    这是我正在使用的代码 我对 LINQ 还是有点陌生 所以这是一项正在进行的工作 具体来说 我想从此查询中获取结果 大约 7 列字符串 整数和日期时间 并将它们返回到调用包含此 LINQ to SQL 查询的方法的方法 一个简单的代码示例将非
  • 使用 QuickBooks Online (QBO) Intuit 合作伙伴平台 (IPP) DevKit 查询具有未结余额的所有发票

    我正在尝试使用 IPP 查询所有具有未结余额的发票 但我不断收到 0 个结果 我在代码中做错了什么吗 这是我尝试使用应用的过滤执行的 C 代码片段 InvoiceQuery qboInvoiceQuery new InvoiceQuery
  • R:UseMethod(“tbl_vars”)中的错误

    所以我在 R Studio 中运行下面的代码并收到此错误 UseMethod tbl vars 中的错误 tbl vars 没有适用的方法 应用于 字符 类的对象 我不知道如何修复它 因为没有 tbl vars 函数 有人可以帮忙吗 for
  • 由于 MIME 类型不匹配而阻止资源(X-Content-Type-Options:nosniff)

    我正在使用 JavaScript 和 HTML 开发网页 一切正常 当我从 HTML 页面收到以下错误列表时 这很好 The resource from https raw githubusercontent com dataarts da
  • 运行 endpointscfg.py get_swagger_spec 时出错

    我正在尝试按照本指南使用 Google Cloud Endpoints 构建一个项目 App Engine 上的云端点框架快速入门 我陷入了生成 OpenAPI 配置文件的步骤 需要运行以下命令 尝试一 lib endpoints endp
  • 为什么armeabi-v7a与另一个模块的armeabi冲突?

    我的项目中有 2 个模块 模块 1 libs armeabi 模块 2 libs armeabi libs armeabi v7a 为了成功运行该应用程序 我必须删除armeabi v7a完全文件夹 否则 so库位于Module 1 arm
  • MySQL - 时间戳之间的平均差异,不包括周末和非工作时间

    我正在寻找能够平均时间戳之间差异的能力 排除周末和排除非工作时间 仅在 08 00 00 17 00 00 之间 我试图仅使用查询来实现此功能 但如果无法使用 MySQL 则可以回退到 PHP 函数 下面是我当前用来获取平均时间戳差异的函数