ITSM统计分析:提升IT服务管理效能 实施步骤与操作说明

ITSM统计分析:提升IT服务管理效能

一、引言

在当今数字化时代,IT系统已成为企业运营的核心支撑。ITSM(IT Service Management,IT服务管理)系统作为规范和优化IT服务流程的重要工具,在公司IT服务管理中扮演着关键角色。公司借助ITSM系统实现用户服务请求的有效处理,用户提交服务票后,由IT团队(包括内部IT人员和外包人员)协作解决问题。然而,由于每个服务票在处理过程中往往涉及多个环节和人员,如何准确评估ITSM服务质量、确保服务效率成为亟待解决的问题。本文旨在深入探讨ITSM的统计分析方法,通过多维度评估实现对IT服务管理的精准把控。

二、ITSM服务属性分类

ITSM服务票涵盖的服务属性丰富多样,准确的分类是后续评估的基础。

  1. 操作问题:主要涉及用户在日常操作IT系统过程中遇到的各类问题,例如登录失败、软件操作异常等。这类问题通常源于用户操作不当或系统显示问题,解决重点在于指导用户正确操作或排查系统界面显示错误。这部分不应该提ITSM, 可以通过其他管道进行了解学习。
  2. 正常的权限申请:用户因工作需求申请访问特定系统、数据或执行某些操作的权限。权限申请的评估重点在于审核申请的合理性和安全性,确保符合公司的权限管理策略。
  3. 系统bug:指IT系统中存在的缺陷或漏洞,导致系统功能无法正常实现或出现错误结果。识别系统bug需要深入分析问题发生的场景、频率等,以确定其根本原因并进行修复。
  4. 新需求:用户提出的对现有IT系统进行功能扩展、改进或新增功能的需求。新需求的处理不仅要考虑技术可行性,还需评估对业务的影响和优先级。

对服务票进行准确的属性分类,有助于后续按照不同标准进行高效处理和评估。

三、SLA标准与工作时间计算

为确保IT服务的高效性和可靠性,公司针对不同服务属性制定了相应的SLA(Service Level Agreement,服务水平协议)标准。

  1. SLA标准概览:新需求的处理时间通常按需排期,这意味着根据项目的整体计划和资源分配来确定具体的解决时间。而其他类型的服务票,原则上应在3个工作日内完成处理。这一标准旨在平衡服务质量和业务需求,保障IT系统的稳定运行。
  2. 工作时间计算规则:工作时间以工作日计算,排除了周末和法定节假日。精确计算工作时间对于评估服务是否按时交付至关重要,它能够反映出IT团队处理问题的实际效率,并为后续的超SLA判断提供准确依据。

四、开发背景与要解决的问题

在当前的ITSM系统运行过程中,服务票的处理涉及多个内部IT人员和外包人员的协同工作。每个服务票在处理流程中往往会来来回回经过多人之手,且在不同的处理阶段可能会分配给不同的团队或个人,甚至可能涉及外包人员的参与。在此背景下,现有的报表系统已无法满足对ITSM服务票进行精准评估的需求,具体问题如下:

1. 无法准确判断具体环节处理情况及延误原因

现有的报表系统虽然能够追踪服务票的提交和处理状态,但它们的设计初衷主要是从整体流程的角度进行记录,例如按照提票、受理、解决等大的阶段进行统计,而无法提供关于每个处理细节节点的详细信息。这就导致了在进行服务质量评估时存在诸多困难。

首先,由于缺乏对每个细节节点的时间记录和处理人员信息,很难准确判断在服务票处理过程中的某个具体环节是否按时完成,以及是由哪个具体的人员或团队导致了可能的延误。例如,当一个服务票的处理时间超过了预先设定的SLA标准时,无法确定是哪个处理步骤耗时过长,是因为某个内部IT人员的操作复杂,还是外包人员的响应不及时等原因造成的。

2. 责任界定复杂困难

其次,在涉及到多人协作和外包的情况下,责任界定变得十分复杂。当出现服务问题或延误时,很难确定问题究竟出在哪个环节、哪个人或团队身上。如果没有准确的分析和评估手段,就难以对相关责任人进行有效的监督和管理,也无法从根本上解决服务过程中出现的问题,进而影响整个IT服务管理的效率和质量。

3. 难以满足全面深入分析需求

最后,现有的报表系统无法满足对服务票进行全面、深入分析的需求。例如,无法统计每个服务属性在不同处理阶段的总时间、平均时间等关键指标,也就无法发现服务流程中存在的潜在瓶颈和优化点。这使得公司难以对ITSM服务进行针对性的改进和优化,无法持续提升服务质量和用户满意度。

因此,为了实现对每个ITSM服务票进行准确评估的目标,解决现有报表系统无法提供细节信息和难以进行责任界定与问题分析的问题,开发一套专门的统计分析系统变得尤为迫切。通过收集和分析每个服务票在处理过程中的详细细节信息,包括每个节点的处理时间、处理人员等,能够为准确评估服务质量、合理分配责任和持续优化服务流程提供有力支持。这也是本项目的核心目的和意义所在。

五,解决问题的关键步骤

关键步骤的详细说明:

步骤1:开发从网页获取每个细节的节点的内容的代码

  • 目的:由于现有的报表系统无法提供每个服务票处理过程中的详细细节信息,为了实现对ITSM服务票的准确评估,需要通过编写代码从网页上抓取每个服务票在处理过程中各个细节节点的相关内容,如处理时间、处理人员、节点状态等信息。这些详细数据将为后续的分析和评估提供基础。
  • 具体实现方式
    • 技术选型:选择合适的编程语言和相关库来实现网页数据的抓取。例如,Python是一种常用的选择,它具有丰富的第三方库,如BeautifulSoup用于解析HTML页面结构,Selenium用于模拟浏览器操作以应对动态加载的页面。
    • 分析网页结构:对ITSM系统的网页界面进行详细分析,确定需要抓取的细节节点在HTML页面中的位置和标识方式。这可能涉及到查看网页源代码、使用浏览器的开发者工具等,以了解节点的HTML标签、属性等信息。
    • 编写抓取逻辑:根据网页结构分析的结果,编写代码逻辑来定位和提取所需的细节节点内容。例如,使用BeautifulSoup库可以通过查找特定的HTML标签和属性来定位节点,然后获取节点内的文本或属性值作为所需信息。
    • 处理动态加载情况:如果ITSM系统的网页存在动态加载的内容,如通过JavaScript异步加载的数据,可能需要使用Selenium等工具来模拟浏览器操作,等待页面加载完成后再进行数据抓取。
    • 数据清洗和整理:抓取到的数据可能存在一些不规范或不完整的情况,需要进行数据清洗和整理。例如,去除重复数据、处理缺失值、统一数据格式等,以确保数据的质量和一致性。

步骤2:开发数据库存放这些内容

  • 目的:将从网页抓取到的每个服务票的细节节点内容进行有效的存储和管理,以便后续的数据分析和处理。数据库提供了一个结构化的数据存储方式,方便数据的查询、更新和维护。
  • 具体实现方式
    • 数据库选型:根据项目需求和数据特点选择合适的数据库管理系统。在本项目中,选择MySQL作为数据库,它是一种开源的关系型数据库,具有成熟的技术体系和广泛的应用支持。
    • 设计数据库表结构:根据抓取到的数据内容和分析需求,设计合理的数据库表结构。例如,可以创建一个主表来存储服务票的基本信息,如服务票编号、提交时间、提交用户等;再创建一个或多个子表来存储每个服务票的细节节点信息,包括节点编号、所属服务票编号、节点名称、进入时间、离开时间、处理人员等字段。
    • 创建数据库和表:使用数据库管理工具(如MySQL Workbench)或通过编写SQL语句来创建数据库和相应的表结构。在创建表时,需要定义字段的数据类型、约束条件等,以确保数据的完整性和一致性。
    • 建立数据连接:在代码中建立与数据库的连接,以便将抓取到的数据插入到数据库中。这通常涉及到使用相应的数据库驱动程序和连接字符串来配置连接参数。

步骤3:定位属性,计算真实实际的工作时间,并判断是否超SLA,这部分的数据最终要存数据库里(可以用python or stored procedure)

  • 目的:对服务票的处理过程进行深入分析,确定每个服务票的服务属性(如操作问题、权限申请、系统bug、新需求等),计算实际工作时间,并根据SLA标准判断是否超时。这些分析结果将作为评估ITSM服务质量的重要依据,并存储到数据库中以便后续查询和使用。
  • 具体实现方式
    • 属性定位
      • 规则制定:根据服务票的内容和相关业务知识,制定一套属性定位的规则。例如,如果服务票描述中包含特定的关键词(如"权限""申请"等),则可以判断该服务票的服务属性为权限申请;如果描述中涉及到系统故障、错误提示等信息,则可能是系统bug。
      • 文本分析:使用自然语言处理技术对服务票的描述内容进行分析,提取关键信息并匹配相应的属性规则。这可以通过编写Python代码来实现,利用相关的自然语言处理库(如NLTK、spaCy等)进行文本预处理、词法分析、句法分析和语义分析等操作。
    • 工作时间计算
      • 数据提取:从数据库中获取每个服务票的细节节点信息,包括进入时间和离开时间。
      • 时间计算逻辑:根据时间记录的格式,将进入时间和离开时间转换为合适的时间数据类型(如Python中的datetime对象)。然后,通过计算相邻节点之间的时间差来累加实际工作时间。在计算过程中,需要考虑工作日的计算规则,排除周末和法定节假日等非工作时间。
    • SLA判断
      • SLA标准设定:根据不同服务属性对应的SLA标准,在代码中设定相应的判断条件。例如,对于新需求服务属性,按照需排期的规则可能不需要判断是否超时;对于其他服务属性,如操作问题、权限申请等,需要判断实际工作时间是否超过3个工作日。
      • 判断逻辑实现:将计算得到的实际工作时间与设定的SLA标准进行比较,如果实际工作时间超过SLA标准,则标记为超时,并记录超时时长等相关信息。
    • 数据存储
      • Python实现:如果选择使用Python来实现这部分功能,可以使用数据库连接库(如PyMySQL)将计算得到的属性定位结果、实际工作时间和SLA判断结果插入到数据库中相应的表中。在插入数据时,需要确保数据的准确性和完整性,处理好可能出现的异常情况。
      • 存储过程实现:也可以使用数据库的存储过程来实现数据的存储和处理。存储过程是一组预先编译好的SQL语句集合,可以在数据库服务器端执行复杂的业务逻辑。通过编写存储过程,可以提高数据处理的效率和安全性,并且可以方便地在不同的应用程序中调用。

步骤4:利用excel从mySQL数据库取数做出报表

  • 目的:将从数据库中存储的经过分析和处理的数据以直观、清晰的报表形式呈现出来,以便业务人员和管理人员能够快速了解ITSM服务的整体情况、服务质量指标以及存在的问题等,从而为决策提供支持。
  • 具体实现方式
    • 建立Excel与MySQL数据库的连接:在Excel中,可以通过"数据"选项卡中的"获取外部数据"功能来连接到MySQL数据库。选择合适的连接方式(如ODBC连接),并配置相关的连接参数,如数据库服务器地址、用户名、密码、数据库名称等。
    • 编写SQL查询语句:根据报表的需求,在Excel中编写相应的SQL查询语句来从数据库中提取所需的数据。可以使用SELECT语句来选择特定的字段和记录,并通过WHERE子句、GROUP BY子句等进行数据筛选和分组。
    • 设计报表模板:根据数据的分析结果和展示需求,在Excel中设计合适的报表模板。这可能包括设置表格的样式、添加图表(如柱状图、折线图、饼图等)来直观地展示数据、设置数据透视表来进行数据分析等。
    • 自动更新报表数据:为了确保报表数据的及时性和准确性,可以设置Excel表格与数据库的自动更新机制。例如,可以通过VBA宏编程来实现定时刷新数据,或者在工作表中设置数据刷新按钮,方便用户手动更新数据。

关键步骤详解

1.开发网页数据抓取代码

为实现对ITSM服务票细节节点信息的收集,首先需要开发专门的网页数据抓取代码。考虑到ITSM系统的界面特征和数据结构,我们选择了Python作为开发语言,利用其强大的第三方库(如BeautifulSoup、Selenium等)实现数据的提取。

通过分析目标网页的HTML结构,编写代码定位到每个需要抓取的细节节点,如操作时间戳、处理人员信息等。

这段代码实现了一个从ITSM(IT服务管理)系统中抓取服务票细节节点信息,并将这些信息存储到MySQL数据库中的过程。以下是对该代码的详细说明:

主要类和方法

  1. ItsmService 类

    • 这个类包含了与ITSM系统交互并处理数据的方法。
  2. getAList 方法

    • 通过调用CallItsmService(cockie).getAuthList()获取授权列表的数据。
    • 解析返回的JSON数据,检查状态码是否为100000表示成功。
    • 遍历记录,对于每个记录,如果数据库中不存在相同bizKey的数据,则插入新记录;否则,更新或跳过。
    • 插入成功后,调用gethistory方法进一步处理历史记录。
  3. gethistory 方法

    • 根据工作订单ID (workOrderId) 获取历史记录。
    • 同样地,解析返回的JSON数据,并将其插入到t_main_history表中。
  4. getMainBybizKey 方法

    • 检查特定bizKey在数据库中的存在性,用于避免重复数据插入。
  5. deleteMainBybizKey 方法

    • 删除特定bizKey相关的主记录及其历史记录,确保数据的一致性和准确性。

关键点

  • 依赖库 :使用了json, time, 自定义的CallItsmService类, 和OpertionMysqlUtil类来处理HTTP请求、时间转换以及数据库连接和操作。
  • 错误处理 :每个数据库操作都包含在try-except-finally块中,以确保即使发生异常也能正确关闭数据库连接。
  • SQL注入防护:虽然示例中直接构建了SQL语句,但在实际应用中应考虑使用参数化查询来防止SQL注入攻击。
  • 性能考虑:频繁地打开和关闭数据库连接可能会影响性能,在高并发场景下可以考虑使用数据库连接池。

注意事项

  • 确保提供的cookie是有效的,并且具有访问所需资源的权限。
  • 在生产环境中运行此脚本前,应该对SQL语句进行仔细审查,特别是考虑到SQL注入的风险。
  • 根据实际情况调整数据库连接和其他配置。

python 详细代码

import os
import time
import json
from CallItsmService import CallItsmService
from lsh.rpa.bi.bi_mysql_Utils import OpertionMysqlUtil

cockie ='xxxx'

class ItsmService:
    def __init__(self):
        print('1')

    def getAList(self):
        c = CallItsmService(cockie)
            # "HWWAFSESID=e95e1730953e8b8433; HWWAFSESTIME=1698628235004; CASTGC=TGT-100079bf-505d-40dd-aa41-00dbec7cfce6; aops-sessionId=a25ed6a3-2053-43aa-a57a-e10d93b8b33c; SESSION=YTI1ZWQ2YTMtMjA1My00M2FhLWE1N2EtZTEwZDkzYjhiMzNj")
        jsondata = c.getAuthList()
        print(jsondata)
        print(json.loads(jsondata)['code'])
        data = json.loads(jsondata)
        try:
            conn = OpertionMysqlUtil.getItsmMysqlConn()
            if data is not None and data['code']== 100000:
                records = data['data']['records']
                if records:
                    for re in records:
                        print(re)
                        id = re['id']
                        title = re['title']
                        bizKey = re['bizKey']
                        mdlDefName = re['mdlDefName']
                        slaServiceStatus = re['slaServiceStatus']['name']
                        dataStatus = re['dataStatus']
                        createdTime = re['createdTime']
                        flag = itsmService.getMainBybizKey(bizKey)
                        if flag >= 1:
                            print('该数据已存在,无需处理')
                        else:
                            itsmService.deleteMainBybizKey(bizKey)
                            sql = "INSERT INTO `itsm`.`t_main` (`id`, `bizKey`, `title`, `dataStatus`, `slaServiceStatus`, `createdTime`, `mdlDefName`)   VALUES ('%s','%s', '%s', '%s', '%s', '%s', '%s');"% (id, bizKey,title,dataStatus,slaServiceStatus,createdTime,mdlDefName)
                            print(sql)
                            cursor = conn.cursor()
                            cursor.execute(sql)
                            conn.commit()
                            print("插入成功")
                            itsmService.gethistory(id,bizKey)
        except Exception as e:
            print('处理失败:', e)
            print(e)
        finally:
            conn.close()
            # print("1111")
    def gethistory(self,workOrderId,bizKey):

        c = CallItsmService(cockie)
        jsondata = c.getHistoryList(workOrderId)
        print(jsondata)
        print(json.loads(jsondata)['code'])
        data = json.loads(jsondata)
        try:
            conn = OpertionMysqlUtil.getItsmMysqlConn()
            if data is not None and data['code'] == 100000:
                batchGroupHisRecordLists = data['data']['batchGroupHisRecordList']
                if batchGroupHisRecordLists:
                    for re in batchGroupHisRecordLists:
                        if re['mdlHisRecordList']:
                            for hisRe in re['mdlHisRecordList']:
                                id = hisRe['dataContent']['id']
                                operatedTime = hisRe['dataContent']['operatedTime']
                                time_local = time.localtime(int(operatedTime/1000))
                                # 转换成新的时间格式(2016-05-05 20:28:54)
                                dt = time.strftime("%Y-%m-%d %H:%M:%S", time_local)
                                content = hisRe['dataContent']['content']
                                operateUserName = hisRe['dataContent']['contentTplData']['operateUserName']
                                currentNodeName = hisRe['dataContent']['contentTplData']['currentNodeName']
                                sql = "INSERT INTO `itsm`.`t_main_history` (`id`, `bizKey`,`operateUserName`, `currentNodeName`, `content`, `operatedTime`)   VALUES ('%s','%s','%s', '%s', '%s', '%s');" % (id,bizKey, operateUserName, currentNodeName, content, dt)
                                print(sql)
                                cursor = conn.cursor()
                                cursor.execute(sql)
                                conn.commit()
                                print("插入成功")
                        else:
                            id = re['batchGroupId']
                            if re['mutiNormalTaskHandlerVo']:
                                for m in re['mutiNormalTaskHandlerVo']:
                                    operateUserName = m['userName']
                            currentNodeName = re['nodeName']
                            content = re['nodeName']
                            time_local = time.localtime(int(re['startTime'] / 1000))
                            # 转换成新的时间格式(2016-05-05 20:28:54)
                            dt = time.strftime("%Y-%m-%d %H:%M:%S", time_local)
                            sql = "INSERT INTO `itsm`.`t_main_history` (`id`, `bizKey`,`operateUserName`, `currentNodeName`, `content`, `operatedTime`)   VALUES ('%s','%s','%s', '%s', '%s', '%s');" % (id, bizKey, operateUserName, currentNodeName, content, dt)
                            print(sql)
                            cursor = conn.cursor()
                            cursor.execute(sql)
                            conn.commit()
                            print("插入成功")
        except Exception as e:
            print('处理失败:', e)
            print(e)
        finally:
            conn.close()
            # print("1111")
    def getMainBybizKey(self,bizKey):
        try:
            conn = OpertionMysqlUtil.getItsmMysqlConn()
            sql = "SELECT bizKey FROM t_main WHERE bizKey = '%s' and (dataStatus = '20' or dataStatus = '40');"%bizKey
            cursor = conn.cursor()
            cursor.execute(sql)
            rs = cursor.fetchall()
            return len(rs)
        except Exception as e:
            print('处理失败:', e)
            print(e)
        finally:
            conn.close()
            # print("1111")
    def deleteMainBybizKey(self,bizKey):
        try:
            conn = OpertionMysqlUtil.getItsmMysqlConn()
            sql = "DELETE FROM t_main WHERE bizKey = '%s';"%bizKey
            sql1 = "DELETE FROM t_main_history WHERE bizKey = '%s';" % bizKey
            cursor = conn.cursor()
            cursor.execute(sql)
            cursor.execute(sql1)
            conn.commit()
        except Exception as e:
            print('处理失败:', e)
            print(e)
        finally:
            conn.close()
itsmService = ItsmService()
# itsmService.gethistory('f735517a844de7a39e60bc0e65991478','FSSC2023092900004')
itsmService.getAList()

2 数据库设计与实现

抓取到的数据量庞大且结构复杂,需要设计合理的数据库来进行存储和管理。我们选择了MySQL作为数据库管理系统,设计了包含多张表的结构,以满足不同类型数据的存储需求。

主要表结构及相关字段说明如下:

1. 创建表 t_adrc

描述 :存储公司地址相关信息。
主要字段

  • 公司(主键)、地址号上市的业务类型JCE分析的业务类型JCE的业务类型中国的业务类型PC区域PMA上市的业务类型LSIL上市的业务类型Non省份街道4街道5省份E公司名称名称

2. 创建表 t_checklist

描述 :存储检查清单相关信息。
主要字段

  • ID(主键,自增)、check_id说明时间频率收件人抄送主题内文按工作日历状态创建时间执行时间邮件发送主题邮件回复时间处理人

3. 创建表 t_config_work_upload

描述 :存储配置工作上传相关信息。
主要字段

  • id(主键,自增)、reg_dateitsmnodev_typerel_daterel_modulerel_objis_globalrel_descipuser1user2id_refweight

4. 创建表 t_fssc_h

描述 :存储FSSC工单相关信息。
主要字段

  • 包括创建日期、工单编号(主键部分)、工单标题、当前节点、优先级、案件状态、建单日期、提报人、所在公司代码、所在公司名称、更新人、支持团队、消息处理人、流程名称、类别2、类别3N、共享单据号、解决方案、问题分类、问题类别二级、单据响应状态、单据解决状态、item更新、原因等。

5. 创建表 t_fssc_h_new_req

描述 :存储FSSC工单的新请求相关信息。
主要字段

  • 工单编号(主键)、问题分类

6. 创建表 t_fssc_h_reason_overide

描述 :存储FSSC工单原因覆盖相关信息。
主要字段

  • 工单编号(主键)、问题大类

7. 创建表 t_fssc_h_reason_temp

描述 :存储FSSC工单临时原因相关信息。
主要字段

  • 工单编号(主键)、原因

8. 创建表 t_fssc_h_tempt_fssc_h_temp_distinct

描述 :存储FSSC工单临时信息,后者确保数据唯一性。
主要字段 :与t_fssc_h类似,包含创建日期、工单编号、工单标题、当前节点、优先级、案件状态等。

9. 创建表 t_fssc_mis

描述 :存储FSSC MIS相关信息。
主要字段

  • 工单编号(主键)

10. 创建表 t_holiday

描述 :存储节假日信息。
主要字段

  • ID(主键)、H_DATEweekday

11. 创建表 t_issue_type

描述 :存储问题类型相关信息。
主要字段

  • 问题分类问题大类

12. 创建表 t_item_time

描述 :存储项目时间相关信息。
主要字段

  • id(主键)、bizKeyuser0user1opoptime0optime1secondshoursdayscontentteamoverdue

13. 创建表 t_main

描述 :存储主工单信息。
主要字段

  • id(主键)、bizKeytitledataStatusslaServiceStatuscreatedTimemdlDefName

14. 创建表 t_main_history

描述 :存储主工单历史记录。
主要字段

  • id(主键)、bizKeyoperateUserNamecurrentNodeNamecontentoperatedTime

15. 创建表 t_reason_type

描述 :存储原因类型相关信息。
主要字段

  • 原因问题子类问题大类

16. 创建表 t_remark

描述 :存储备注信息。
主要字段

  • rtimeremark

17. 创建表 t_sla

描述 :存储SLA相关信息。
主要字段

  • 工单编号(主键部分)、roundoptime0optime1optime2teamuser0op1领取人op2处理人领取耗时处理时间

18. 创建表 t_sla0

描述 :存储SLA0相关信息。
主要字段

  • 工单编号(主键)、user0user1optime0optime1daysteam

19. 创建表 t_team

描述 :存储团队信息。
主要字段

  • operateUserNameteamuname

20. 创建表 t_work_log

描述 :存储工作日志信息。
主要字段

  • ID(主键,自增)、unamewdateworktypecontenthours

21. 创建表 t_work_type

描述 :存储工作类型信息。
主要字段

  • worktype工作类型

22-34. 创建视图

描述:这些视图用于汇总和展示不同业务场景下的数据,提供更便捷的查询接口。以下是部分视图的简要说明:

  • v_config_status:汇总配置状态信息,包括月份、周、修改日期、发版日期、案件状态等。
  • v_config_work:汇总配置工作信息,包括月份、周、登记日期、ITSM编号、调整模块等。
  • v_item_effective:计算支持团队的处理效率,包括周、月份、支持团队、处理效率等。
  • v_itsm_cntv_itsm_user_cnt:统计ITSM处理数量,按周、月份、支持团队及消息处理人分类。
  • v_overduev_overdue_simple:汇总超期工单信息,包括月份、工单编号、公司、超期类型等。
  • v_slav_sla_trend:汇总SLA相关信息,展示工单的处理状态和耗时。
  • v_trend 系列视图:汇总不同流程名称下的工单趋势信息,如FSSC系统和电子发票平台。

总结

这些SQL语句主要用于创建数据库表和视图,涵盖了从地址信息、检查清单、配置工作上传、工单管理、节假日信息、问题类型、时间记录、主工单及其历史、原因类型、备注、SLA管理到团队和工作类型的多个业务模块。通过这些表和视图,系统能够有效地存储和管理各种业务数据,并通过视图提供便捷的数据查询和分析接口。

实际的SQL如下:

sql 复制代码
CREATE TABLE t_adrc (类 varchar(10) COLLATE utf8mb4_general_ci, 公司 varchar(10) COLLATE utf8mb4_general_ci NOT NULL, 地址号 varchar(20) COLLATE utf8mb4_general_ci, 上市的业务类型 varchar(10) COLLATE utf8mb4_general_ci, JCE分析的业务类型 varchar(5) COLLATE utf8mb4_general_ci, JCE的业务类型 varchar(50) COLLATE utf8mb4_general_ci, 中国的业务类型 varchar(20) COLLATE utf8mb4_general_ci, PC区域 varchar(50) COLLATE utf8mb4_general_ci, PMA varchar(20) COLLATE utf8mb4_general_ci, 上市的业务类型LSIL varchar(20) COLLATE utf8mb4_general_ci, 上市的业务类型Non varchar(10) COLLATE utf8mb4_general_ci, 省份 varchar(20) COLLATE utf8mb4_general_ci, 街道4 varchar(20) COLLATE utf8mb4_general_ci, 街道5 varchar(30) COLLATE utf8mb4_general_ci, 省份E varchar(30) COLLATE utf8mb4_general_ci, 公司名称 varchar(100) COLLATE utf8mb4_general_ci, 名称 varchar(100) COLLATE utf8mb4_general_ci, PRIMARY KEY (公司)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_checklist (ID int(-1) NOT NULL AUTO_INCREMENT, check_id varchar(20) COLLATE utf8mb4_general_ci, 说明 varchar(64) COLLATE utf8mb4_general_ci, 时间 datetime, 频率 varchar(10) COLLATE utf8mb4_general_ci, 收件人 varchar(100) COLLATE utf8mb4_general_ci, 抄送 varchar(200) COLLATE utf8mb4_general_ci, 主题 varchar(100) COLLATE utf8mb4_general_ci, 内文 text COLLATE utf8mb4_general_ci, 按工作日历 varchar(1) COLLATE utf8mb4_general_ci, 状态 varchar(10) COLLATE utf8mb4_general_ci, 创建时间 datetime, 执行时间 datetime, 邮件发送主题 varchar(100) COLLATE utf8mb4_general_ci, 邮件回复时间 datetime, 处理人 varchar(100) COLLATE utf8mb4_general_ci, PRIMARY KEY (ID)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_config_work_upload (id int(-1) NOT NULL AUTO_INCREMENT, reg_date datetime, itsmno varchar(64) COLLATE utf8mb4_general_ci, dev_type varchar(64), rel_date datetime, rel_module varchar(255) COLLATE utf8mb4_general_ci, rel_obj text COLLATE utf8mb4_general_ci, is_global varchar(16) COLLATE utf8mb4_general_ci, rel_descip text COLLATE utf8mb4_general_ci, user1 varchar(16) COLLATE utf8mb4_general_ci, user2 varchar(16) COLLATE utf8mb4_general_ci, id_ref int(-1), weight float, PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_fssc_h (创建日期 datetime, 工单编号 varchar(255) COLLATE utf8mb4_general_ci, 工单标题 varchar(255) COLLATE utf8mb4_general_ci, 当前节点 varchar(255) COLLATE utf8mb4_general_ci, 优先级 varchar(16) COLLATE utf8mb4_general_ci, 案件状态 varchar(16) COLLATE utf8mb4_general_ci, 建单日期 date, 提报人 varchar(16) COLLATE utf8mb4_general_ci, 所在公司代码 varchar(10) COLLATE utf8mb4_general_ci, 所在公司名称 varchar(255) COLLATE utf8mb4_general_ci, 更新人 varchar(16) COLLATE utf8mb4_general_ci, 支持团队 varchar(16) COLLATE utf8mb4_general_ci, 消息处理人 varchar(255) COLLATE utf8mb4_general_ci, 流程名称 varchar(64) COLLATE utf8mb4_general_ci, 类别2 varchar(64) COLLATE utf8mb4_general_ci, 类别3N varchar(64) COLLATE utf8mb4_general_ci, 共享单据号 varchar(256) COLLATE utf8mb4_general_ci, 解决方案 text COLLATE utf8mb4_general_ci, 问题分类 varchar(64) COLLATE utf8mb4_general_ci, 问题类别二级 varchar(64) COLLATE utf8mb4_general_ci, 单据响应状态 varchar(16) COLLATE utf8mb4_general_ci, 单据解决状态 varchar(16) COLLATE utf8mb4_general_ci, item更新 int(-1), 原因 varchar(64) COLLATE utf8mb4_general_ci) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_fssc_h_new_req (工单编号 varchar(255) COLLATE utf8mb4_general_ci, 问题分类 varchar(64) COLLATE utf8mb4_general_ci) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_fssc_h_reason_overide (工单编号 varchar(255) COLLATE utf8mb4_general_ci, 问题大类 varchar(64) COLLATE utf8mb4_general_ci) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_fssc_h_reason_temp (工单编号 varchar(255) COLLATE utf8mb4_general_ci, 原因 varchar(64) COLLATE utf8mb4_general_ci) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_fssc_h_temp (创建日期 datetime, 工单编号 varchar(255) COLLATE utf8mb4_general_ci, 工单标题 varchar(255) COLLATE utf8mb4_general_ci, 当前节点 varchar(255) COLLATE utf8mb4_general_ci, 优先级 varchar(16) COLLATE utf8mb4_general_ci, 案件状态 varchar(16) COLLATE utf8mb4_general_ci, 建单日期 date, 提报人 varchar(16) COLLATE utf8mb4_general_ci, 所在公司代码 varchar(10) COLLATE utf8mb4_general_ci, 所在公司名称 varchar(255) COLLATE utf8mb4_general_ci, 更新人 varchar(16) COLLATE utf8mb4_general_ci, 支持团队 varchar(16) COLLATE utf8mb4_general_ci, 消息处理人 varchar(255) COLLATE utf8mb4_general_ci, 流程名称 varchar(64) COLLATE utf8mb4_general_ci, 类别2 varchar(64) COLLATE utf8mb4_general_ci, 类别3N varchar(64) COLLATE utf8mb4_general_ci, 共享单据号 varchar(255) COLLATE utf8mb4_general_ci, 解决方案 text COLLATE utf8mb4_general_ci, 问题分类 varchar(64) COLLATE utf8mb4_general_ci, 问题类别二级 varchar(64) COLLATE utf8mb4_general_ci, 单据响应状态 varchar(16) COLLATE utf8mb4_general_ci, 单据解决状态 varchar(16) COLLATE utf8mb4_general_ci) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_fssc_h_temp_distinct (创建日期 datetime, 工单编号 varchar(255) COLLATE utf8mb4_general_ci, 工单标题 varchar(255) COLLATE utf8mb4_general_ci, 当前节点 varchar(255) COLLATE utf8mb4_general_ci, 优先级 varchar(16) COLLATE utf8mb4_general_ci, 案件状态 varchar(16) COLLATE utf8mb4_general_ci, 建单日期 date, 提报人 varchar(16) COLLATE utf8mb4_general_ci, 所在公司代码 varchar(10) COLLATE utf8mb4_general_ci, 所在公司名称 varchar(255) COLLATE utf8mb4_general_ci, 更新人 varchar(16) COLLATE utf8mb4_general_ci, 支持团队 varchar(16) COLLATE utf8mb4_general_ci, 消息处理人 varchar(255) COLLATE utf8mb4_general_ci, 流程名称 varchar(64) COLLATE utf8mb4_general_ci, 类别2 varchar(64) COLLATE utf8mb4_general_ci, 类别3N varchar(64) COLLATE utf8mb4_general_ci, 共享单据号 varchar(255) COLLATE utf8mb4_general_ci, 解决方案 text COLLATE utf8mb4_general_ci, 问题分类 varchar(64) COLLATE utf8mb4_general_ci, 问题类别二级 varchar(64) COLLATE utf8mb4_general_ci, 单据响应状态 varchar(16) COLLATE utf8mb4_general_ci, 单据解决状态 varchar(16) COLLATE utf8mb4_general_ci) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_fssc_mis (工单编号 varchar(255) COLLATE utf8mb4_general_ci) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_holiday (ID varchar(8) COLLATE utf8mb4_general_ci NOT NULL, H_DATE date NOT NULL, weekday int(-1), PRIMARY KEY (ID)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_issue_type (问题分类 varchar(64) COLLATE utf8mb4_general_ci, 问题大类 varchar(16) COLLATE utf8mb4_general_ci) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_item_time (id varchar(255) COLLATE utf8mb4_general_ci NOT NULL, bizKey varchar(255) COLLATE utf8mb4_general_ci, user0 varchar(255) COLLATE utf8mb4_general_ci, user1 varchar(255) COLLATE utf8mb4_general_ci, op varchar(64) COLLATE utf8mb4_general_ci, optime0 datetime, optime1 datetime, seconds float, hours float, days float, content text COLLATE utf8mb4_general_ci, team varchar(16) COLLATE utf8mb4_general_ci, overdue int(-1) DEFAULT 0, PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_main (id varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'FSSC工单号', bizKey varchar(255) COLLATE utf8mb4_general_ci, title varchar(255) COLLATE utf8mb4_general_ci COMMENT '标题', dataStatus varchar(255) COLLATE utf8mb4_general_ci, slaServiceStatus varchar(255) COLLATE utf8mb4_general_ci, createdTime datetime, mdlDefName varchar(255) COLLATE utf8mb4_general_ci COMMENT '系统来源', PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_main_history (id varchar(255) COLLATE utf8mb4_general_ci NOT NULL, bizKey varchar(255) COLLATE utf8mb4_general_ci, operateUserName varchar(255) COLLATE utf8mb4_general_ci, currentNodeName varchar(255) COLLATE utf8mb4_general_ci, content text COLLATE utf8mb4_general_ci, operatedTime datetime, PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_reason_type (原因 varchar(128) COLLATE utf8mb4_general_ci, 问题子类 varchar(64) COLLATE utf8mb4_general_ci, 问题大类 varchar(16) COLLATE utf8mb4_general_ci) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_remark (rtime datetime, remark text COLLATE utf8mb4_general_ci) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_sla (工单编号 varchar(255) COLLATE utf8mb4_general_ci NOT NULL, round int(-1) NOT NULL, optime0 datetime, optime1 datetime, optime2 datetime, team varchar(16) COLLATE utf8mb4_general_ci, user0 varchar(255) COLLATE utf8mb4_general_ci, op1领取人 varchar(255) COLLATE utf8mb4_general_ci, op2处理人 varchar(255) COLLATE utf8mb4_general_ci, 领取耗时 float, 处理时间 float, PRIMARY KEY (工单编号, round)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_sla0 (工单编号 varchar(255) COLLATE utf8mb4_general_ci, user0 varchar(255) COLLATE utf8mb4_general_ci, user1 varchar(255) COLLATE utf8mb4_general_ci, optime0 datetime, optime1 datetime, days float, team varchar(16) COLLATE utf8mb4_general_ci) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_team (operateUserName varchar(255) COLLATE utf8mb4_general_ci, team varchar(16) COLLATE utf8mb4_general_ci, uname varchar(16) COLLATE utf8mb4_general_ci) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_work_log (uname varchar(16) COLLATE utf8mb4_general_ci, wdate date, worktype varchar(256) COLLATE utf8mb4_general_ci, content text COLLATE utf8mb4_general_ci, hours float, ID int(-1) NOT NULL AUTO_INCREMENT, PRIMARY KEY (ID)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE t_work_type (worktype varchar(256) COLLATE utf8mb4_general_ci, 工作类型 varchar(16) COLLATE utf8mb4_general_ci) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE VIEW v_config_status (月份, 周, 修改日, 修改月, 发版日, team, 处理人, ITSM关联号, 新案件状态, 问题大类, 建单日期, 工单编号, 工单标题, 优先级, 案件状态, 配置描述, 天数, 当前节点) AS select `h`.`月份` AS `月份`,`h`.`周` AS `周`,`c`.`reg_date` AS `修改日`,date_format(`c`.`reg_date`,'%Y-%m') AS `修改月`,`c`.`rel_date` AS `发版日`,`t`.`team` AS `team`,`c`.`user1` AS `处理人`,substring_index(`c`.`itsmno`,'\n',1) AS `ITSM关联号`,`h`.`新案件状态` AS `新案件状态`,ifnull(`h`.`问题大类`,`c`.`dev_type`) AS `问题大类`,`h`.`建单日期` AS `建单日期`,`h`.`工单编号` AS `工单编号`,`h`.`工单标题` AS `工单标题`,`h`.`优先级` AS `优先级`,`h`.`案件状态` AS `案件状态`,`c`.`rel_descip` AS `配置描述`,round((`f_duration`(`h`.`建单日期`,`c`.`rel_date`) / 32400),1) AS `天数`,`h`.`当前节点` AS `当前节点` from ((`t_config_work_upload` `c` left join `v_trend` `h` on((substring_index(`c`.`itsmno`,'\n',1) = `h`.`工单编号`))) left join `t_team` `t` on((`t`.`operateUserName` = `c`.`user1`)));
CREATE VIEW v_config_work (月份, 周, 登记日, itsmno, 发版日, 调整模块, 涉及对象, team, 处理人, id, weight) AS select date_format(`a`.`reg_date`,'%Y%m') AS `月份`,week(`a`.`reg_date`,0) AS `周`,date_format(`a`.`reg_date`,'%Y-%m-%d') AS `登记日`,`a`.`itsmno` AS `itsmno`,date_format(`a`.`rel_date`,'%Y-%m-%d') AS `发版日`,`a`.`rel_module` AS `调整模块`,`a`.`rel_obj` AS `涉及对象`,`u`.`team` AS `team`,`u`.`uname` AS `处理人`,`a`.`id` AS `id`,`a`.`weight` AS `weight` from (`t_config_work_upload` `a` join `t_team` `u` on((`a`.`user1` = `u`.`operateUserName`)));
CREATE VIEW v_item_effective (周, 月份, 支持团队, 处理效率, itsm处理数量, ITSM花费时数) AS select `i`.`周` AS `周`,`i`.`月份` AS `月份`,`i`.`支持团队` AS `支持团队`,round((`i`.`itsm处理数量` / `h`.`ITSM花费时数`),1) AS `处理效率`,`i`.`itsm处理数量` AS `itsm处理数量`,`h`.`ITSM花费时数` AS `ITSM花费时数` from (`v_work_hours_sum` `h` join `v_itsm_cnt` `i` on(((`h`.`周` = `i`.`周`) and (`h`.`team` = `i`.`支持团队`))));
CREATE VIEW v_itsm_cnt (周, 月份, 支持团队, itsm处理数量) AS select `v_trend`.`周` AS `周`,`v_trend`.`月份` AS `月份`,`v_trend`.`支持团队` AS `支持团队`,count(`v_trend`.`工单编号`) AS `itsm处理数量` from `v_trend` where (`v_trend`.`案件状态` in ('已完成','已关闭')) group by `v_trend`.`周`,`v_trend`.`月份`,`v_trend`.`支持团队`;
CREATE VIEW v_itsm_user_cnt (周, 月份, 支持团队, 消息处理人, itsm处理数量) AS select `v_trend`.`周` AS `周`,`v_trend`.`月份` AS `月份`,`v_trend`.`支持团队` AS `支持团队`,`v_trend`.`消息处理人` AS `消息处理人`,count(`v_trend`.`工单编号`) AS `itsm处理数量` from `v_trend` where (`v_trend`.`案件状态` in ('已完成','已关闭')) group by `v_trend`.`周`,`v_trend`.`月份`,`v_trend`.`支持团队`,`v_trend`.`消息处理人`;
CREATE VIEW v_overdue (月份, 建单日期, 工单编号, 工单标题, 优先级, 案件状态, 天数, 超期类型, 提报人, 公司, 简称, 公司名, PC区域, 支持团队, 消息处理人, 问题大类, 类别2, 类别3N, 问题分类, 问题类别二级) AS select `h`.`月份` AS `月份`,`h`.`建单日期` AS `建单日期`,`h`.`工单编号` AS `工单编号`,`h`.`工单标题` AS `工单标题`,`h`.`优先级` AS `优先级`,`h`.`案件状态` AS `案件状态`,round((`f_duration`(`h`.`建单日期`,now()) / 32400),1) AS `天数`,'已超期,在处理中' AS `超期类型`,`h`.`提报人` AS `提报人`,`h`.`公司` AS `公司`,`h`.`简称` AS `简称`,`h`.`公司名` AS `公司名`,`h`.`PC区域` AS `PC区域`,`h`.`支持团队` AS `支持团队`,`h`.`消息处理人` AS `消息处理人`,`h`.`问题大类` AS `问题大类`,`h`.`类别2` AS `类别2`,`h`.`类别3N` AS `类别3N`,`h`.`问题分类` AS `问题分类`,`h`.`问题类别二级` AS `问题类别二级` from `v_trend` `h` where ((`h`.`当前节点` in ('一级人员处理','处理人')) and (round((`f_duration`(`h`.`建单日期`,now()) / 32400),1) > 3)) union all select `h`.`月份` AS `月份`,`h`.`建单日期` AS `建单日期`,`h`.`工单编号` AS `工单编号`,`h`.`工单标题` AS `工单标题`,`h`.`优先级` AS `优先级`,`h`.`案件状态` AS `案件状态`,round(`i`.`days`,1) AS `天数`,'单次处理超期3天以上' AS `超期类型`,`h`.`提报人` AS `提报人`,`h`.`公司` AS `公司`,`h`.`简称` AS `简称`,`h`.`公司名` AS `公司名`,`h`.`PC区域` AS `PC区域`,`t`.`team` AS `支持团队`,`i`.`user1` AS `消息处理人`,`h`.`问题大类` AS `问题大类`,`h`.`类别2` AS `类别2`,`h`.`类别3N` AS `类别3N`,`h`.`问题分类` AS `问题分类`,`h`.`问题类别二级` AS `问题类别二级` from ((`v_trend` `h` left join `t_item_time` `i` on((`h`.`工单编号` = `i`.`bizKey`))) left join `t_team` `t` on((`i`.`user1` = `t`.`operateUserName`))) where ((`i`.`days` > 3) and (`t`.`team` is not null));
CREATE VIEW v_overdue_simple (月份, 工单编号, 工单标题, 公司, 简称, 提报人, 问题大类, 支持团队, 超期类型) AS select distinct `v_overdue`.`月份` AS `月份`,`v_overdue`.`工单编号` AS `工单编号`,`v_overdue`.`工单标题` AS `工单标题`,`v_overdue`.`公司` AS `公司`,`v_overdue`.`简称` AS `简称`,`v_overdue`.`提报人` AS `提报人`,`v_overdue`.`问题大类` AS `问题大类`,`v_overdue`.`支持团队` AS `支持团队`,`v_overdue`.`超期类型` AS `超期类型` from `v_overdue`;
CREATE VIEW v_sla (创建日期, 工单编号, 工单标题, 优先级, 案件状态, 建单日期, 提报人, 公司代码, 所在公司名称, PC区域, 支持团队, 消息处理人, user0, user1, op, optime0, optime1, days, content, team, overdue, 类别2, 类别3N, 解决方案, 问题分类, 问题类别二级, 单据响应状态, 单据解决状态, item更新) AS select `h`.`创建日期` AS `创建日期`,`h`.`工单编号` AS `工单编号`,`h`.`工单标题` AS `工单标题`,`h`.`优先级` AS `优先级`,`h`.`案件状态` AS `案件状态`,`h`.`建单日期` AS `建单日期`,`h`.`提报人` AS `提报人`,left(concat(`h`.`所在公司代码`),4) AS `公司代码`,`h`.`所在公司名称` AS `所在公司名称`,`a`.`PC区域` AS `PC区域`,`h`.`支持团队` AS `支持团队`,`h`.`消息处理人` AS `消息处理人`,`i`.`user0` AS `user0`,`i`.`user1` AS `user1`,`i`.`op` AS `op`,`i`.`optime0` AS `optime0`,`i`.`optime1` AS `optime1`,`i`.`days` AS `days`,`i`.`content` AS `content`,`t`.`team` AS `team`,`i`.`overdue` AS `overdue`,`h`.`类别2` AS `类别2`,`h`.`类别3N` AS `类别3N`,`h`.`解决方案` AS `解决方案`,`h`.`问题分类` AS `问题分类`,`h`.`问题类别二级` AS `问题类别二级`,`h`.`单据响应状态` AS `单据响应状态`,`h`.`单据解决状态` AS `单据解决状态`,`h`.`item更新` AS `item更新` from (((`t_fssc_h` `h` left join `t_item_time` `i` on((`h`.`工单编号` = `i`.`bizKey`))) left join `t_adrc` `a` on((left(concat(`h`.`所在公司代码`),4) = `a`.`公司`))) left join `t_team` `t` on((`i`.`user1` = `t`.`operateUserName`)));
CREATE VIEW v_sla_trend (月份, 周, 建单日期, 工单编号, round, optime0, optime1, optime2, op, team, user0, op1领取人, op2处理人, 领取耗时, 处理时间, 问题大类, 公司, 简称, 公司名, 优先级, 案件状态, 工单标题, 新案件状态) AS select `v_trend`.`月份` AS `月份`,`v_trend`.`周` AS `周`,`v_trend`.`建单日期` AS `建单日期`,`t_sla`.`工单编号` AS `工单编号`,`t_sla`.`round` AS `round`,`t_sla`.`optime0` AS `optime0`,`t_sla`.`optime1` AS `optime1`,`t_sla`.`optime2` AS `optime2`,`t`.`op` AS `op`,`t_sla`.`team` AS `team`,`t_sla`.`user0` AS `user0`,ifnull(`u1`.`uname`,`t_sla`.`op1领取人`) AS `op1领取人`,ifnull(`u2`.`uname`,`t_sla`.`op2处理人`) AS `op2处理人`,`t_sla`.`领取耗时` AS `领取耗时`,`t_sla`.`处理时间` AS `处理时间`,`v_trend`.`问题大类` AS `问题大类`,`v_trend`.`公司` AS `公司`,`v_trend`.`简称` AS `简称`,`v_trend`.`公司名` AS `公司名`,`v_trend`.`优先级` AS `优先级`,`v_trend`.`案件状态` AS `案件状态`,`v_trend`.`工单标题` AS `工单标题`,`v_trend`.`新案件状态` AS `新案件状态` from ((((`t_sla` join `v_trend` on((`t_sla`.`工单编号` = `v_trend`.`工单编号`))) left join `t_team` `u1` on((`u1`.`operateUserName` = `t_sla`.`op1领取人`))) left join `t_team` `u2` on((`u2`.`operateUserName` = `t_sla`.`op2处理人`))) left join `t_item_time` `t` on(((`t_sla`.`工单编号` = `t`.`bizKey`) and (`t_sla`.`optime2` = `t`.`optime1`) and (`t_sla`.`op2处理人` = `t`.`user1`))));
CREATE VIEW v_trend (月份, 周, 建单日期, 工单编号, 工单标题, 优先级, 案件状态, 当前节点, 新案件状态, 提报人, 支持团队, 消息处理人, 问题大类, 问题子类, 公司, 简称, 公司名, PC区域, 类别2, 类别3N, 问题分类, 问题类别二级, 原因) AS select distinct date_format(`h`.`创建日期`,'%Y%m') AS `月份`,week(`h`.`创建日期`,1) AS `周`,`h`.`建单日期` AS `建单日期`,`h`.`工单编号` AS `工单编号`,`h`.`工单标题` AS `工单标题`,`h`.`优先级` AS `优先级`,`h`.`案件状态` AS `案件状态`,`h`.`当前节点` AS `当前节点`,(case when ((`h`.`案件状态` = '处理中') and ((`h`.`当前节点` = '用户确认') or (`h`.`当前节点` = '专人回访'))) then '已解决用户确认中' else `h`.`案件状态` end) AS `新案件状态`,`h`.`提报人` AS `提报人`,ifnull(`tm`.`team`,`h`.`支持团队`) AS `支持团队`,ifnull(`tm`.`uname`,`h`.`消息处理人`) AS `消息处理人`,ifnull(`o`.`问题大类`,(case when (((`h`.`案件状态` = '处理中') or (`h`.`案件状态` = '待领取')) and (`h`.`当前节点` <> '用户确认') and (`t`.`问题大类` is null) and (`n`.`问题分类` is null)) then '问题处理中尚无分类' when ((`h`.`创建日期` > '2024-08-01') and (ifnull(`r`.`问题大类`,`t`.`问题大类`) = '数据修正')) then '正常申请' else ifnull(`n`.`问题分类`,ifnull(`r`.`问题大类`,ifnull(`t`.`问题大类`,'回退'))) end)) AS `问题大类`,`r`.`问题子类` AS `问题子类`,`a`.`公司` AS `公司`,`a`.`街道4` AS `简称`,`h`.`所在公司名称` AS `公司名`,`a`.`PC区域` AS `PC区域`,`h`.`类别2` AS `类别2`,`h`.`类别3N` AS `类别3N`,`h`.`问题分类` AS `问题分类`,`h`.`问题类别二级` AS `问题类别二级`,`h`.`原因` AS `原因` from ((((((`t_fssc_h` `h` left join `t_adrc` `a` on((left(concat(`h`.`所在公司代码`),4) = `a`.`公司`))) left join `t_fssc_h_new_req` `n` on((`h`.`工单编号` = `n`.`工单编号`))) left join `t_issue_type` `t` on((`h`.`问题分类` = `t`.`问题分类`))) left join `t_reason_type` `r` on((`h`.`原因` = `r`.`原因`))) left join `t_team` `tm` on((`tm`.`operateUserName` = `h`.`消息处理人`))) left join `t_fssc_h_reason_overide` `o` on((`h`.`工单编号` = `o`.`工单编号`)));
CREATE VIEW v_trend_fssc (月份, 周, 建单日期, 工单编号, 工单标题, 优先级, 案件状态, 当前节点, 新案件状态, 提报人, 支持团队, 消息处理人, 问题大类, 问题子类, 公司, 简称, 公司名, PC区域, 类别2, 类别3N, 问题分类, 问题类别二级, 原因) AS select distinct date_format(`h`.`创建日期`,'%Y%m') AS `月份`,week(`h`.`创建日期`,1) AS `周`,`h`.`建单日期` AS `建单日期`,`h`.`工单编号` AS `工单编号`,`h`.`工单标题` AS `工单标题`,`h`.`优先级` AS `优先级`,`h`.`案件状态` AS `案件状态`,`h`.`当前节点` AS `当前节点`,(case when ((`h`.`案件状态` = '处理中') and ((`h`.`当前节点` = '用户确认') or (`h`.`当前节点` = '专人回访'))) then '已解决用户确认中' else `h`.`案件状态` end) AS `新案件状态`,`h`.`提报人` AS `提报人`,ifnull(`tm`.`team`,`h`.`支持团队`) AS `支持团队`,ifnull(`tm`.`uname`,`h`.`消息处理人`) AS `消息处理人`,ifnull(`o`.`问题大类`,(case when (((`h`.`案件状态` = '处理中') or (`h`.`案件状态` = '待领取')) and (`h`.`当前节点` <> '用户确认') and (`t`.`问题大类` is null) and (`n`.`问题分类` is null)) then '问题处理中尚无分类' when ((`h`.`创建日期` > '2024-08-01') and (ifnull(`r`.`问题大类`,`t`.`问题大类`) = '数据修正')) then '正常申请' else ifnull(`n`.`问题分类`,ifnull(`r`.`问题大类`,ifnull(`t`.`问题大类`,'回退'))) end)) AS `问题大类`,`r`.`问题子类` AS `问题子类`,`a`.`公司` AS `公司`,`a`.`街道4` AS `简称`,`h`.`所在公司名称` AS `公司名`,`a`.`PC区域` AS `PC区域`,`h`.`类别2` AS `类别2`,`h`.`类别3N` AS `类别3N`,`h`.`问题分类` AS `问题分类`,`h`.`问题类别二级` AS `问题类别二级`,`h`.`原因` AS `原因` from ((((((`t_fssc_h` `h` left join `t_adrc` `a` on((left(concat(`h`.`所在公司代码`),4) = `a`.`公司`))) left join `t_fssc_h_new_req` `n` on((`h`.`工单编号` = `n`.`工单编号`))) left join `t_issue_type` `t` on((`h`.`问题分类` = `t`.`问题分类`))) left join `t_reason_type` `r` on((`h`.`原因` = `r`.`原因`))) left join `t_team` `tm` on((`tm`.`operateUserName` = `h`.`消息处理人`))) left join `t_fssc_h_reason_overide` `o` on((`h`.`工单编号` = `o`.`工单编号`))) where (`h`.`流程名称` = 'FSSC系统');
CREATE VIEW v_trend_inv (月份, 周, 建单日期, 工单编号, 工单标题, 优先级, 案件状态, 当前节点, 新案件状态, 提报人, 支持团队, 消息处理人, 问题大类, 问题子类, 公司, 简称, 公司名, PC区域, 类别2, 类别3N, 问题分类, 问题类别二级, 原因) AS select distinct date_format(`h`.`创建日期`,'%Y%m') AS `月份`,week(`h`.`创建日期`,1) AS `周`,`h`.`建单日期` AS `建单日期`,`h`.`工单编号` AS `工单编号`,`h`.`工单标题` AS `工单标题`,`h`.`优先级` AS `优先级`,`h`.`案件状态` AS `案件状态`,`h`.`当前节点` AS `当前节点`,(case when ((`h`.`案件状态` = '处理中') and ((`h`.`当前节点` = '用户确认') or (`h`.`当前节点` = '专人回访'))) then '已解决用户确认中' else `h`.`案件状态` end) AS `新案件状态`,`h`.`提报人` AS `提报人`,ifnull(`tm`.`team`,`h`.`支持团队`) AS `支持团队`,ifnull(`tm`.`uname`,`h`.`消息处理人`) AS `消息处理人`,(case when (((`h`.`案件状态` = '处理中') or (`h`.`案件状态` = '待领取')) and (`h`.`当前节点` <> '用户确认') and (`t`.`问题大类` is null) and (`n`.`问题分类` is null)) then '问题处理中尚无分类' when ((`h`.`创建日期` > '2024-08-01') and (ifnull(`r`.`问题大类`,`t`.`问题大类`) = '数据修正')) then '正常申请' else ifnull(`n`.`问题分类`,ifnull(`r`.`问题大类`,ifnull(`t`.`问题大类`,'回退'))) end) AS `问题大类`,`r`.`问题子类` AS `问题子类`,`a`.`公司` AS `公司`,`a`.`街道4` AS `简称`,`h`.`所在公司名称` AS `公司名`,`a`.`PC区域` AS `PC区域`,`h`.`类别2` AS `类别2`,`h`.`类别3N` AS `类别3N`,`h`.`问题分类` AS `问题分类`,`h`.`问题类别二级` AS `问题类别二级`,`h`.`原因` AS `原因` from ((((((`t_fssc_h` `h` left join `t_adrc` `a` on((left(concat(`h`.`所在公司代码`),4) = `a`.`公司`))) left join `t_fssc_h_new_req` `n` on((`h`.`工单编号` = `n`.`工单编号`))) left join `t_issue_type` `t` on((`h`.`问题分类` = `t`.`问题分类`))) left join `t_reason_type` `r` on((`h`.`原因` = `r`.`原因`))) left join `t_team` `tm` on((`tm`.`operateUserName` = `h`.`消息处理人`))) left join `t_fssc_h_reason_overide` `o` on((`h`.`工单编号` = `o`.`工单编号`))) where (`h`.`流程名称` = '电子发票平台');
CREATE VIEW v_user_effective (周, 月份, 支持团队, 人员, 处理效率, itsm处理数量, ITSM花费时数) AS select `i`.`周` AS `周`,`i`.`月份` AS `月份`,`i`.`支持团队` AS `支持团队`,`i`.`消息处理人` AS `人员`,round((`i`.`itsm处理数量` / `h`.`ITSM花费时数`),1) AS `处理效率`,`i`.`itsm处理数量` AS `itsm处理数量`,`h`.`ITSM花费时数` AS `ITSM花费时数` from (`v_itsm_user_cnt` `i` left join `v_work_hours_sum_user` `h` on(((`h`.`周` = `i`.`周`) and (`h`.`team` = `i`.`支持团队`) and (`h`.`人员` = `i`.`消息处理人`))));
CREATE VIEW v_work (team, uname, 月份, 周, wdate, 工作类型, worktype, content, hours) AS select `m`.`team` AS `team`,`m`.`uname` AS `uname`,date_format(`l`.`wdate`,'%Y%m') AS `月份`,week(`l`.`wdate`,0) AS `周`,`l`.`wdate` AS `wdate`,`t`.`工作类型` AS `工作类型`,`l`.`worktype` AS `worktype`,`l`.`content` AS `content`,`l`.`hours` AS `hours` from ((`t_work_log` `l` join `t_work_type` `t` on((`l`.`worktype` = `t`.`worktype`))) join `t_team` `m` on((`l`.`uname` = `m`.`operateUserName`)));
CREATE VIEW v_work_hours_sum (周, 月份, team, ITSM花费时数) AS select `v_work`.`周` AS `周`,`v_work`.`月份` AS `月份`,`v_work`.`team` AS `team`,sum(`v_work`.`hours`) AS `ITSM花费时数` from `v_work` where (`v_work`.`工作类型` = 'ITSM') group by `v_work`.`周`,`v_work`.`月份`,`v_work`.`team`;
CREATE VIEW v_work_hours_sum_user (周, 月份, team, ITSM花费时数, 人员) AS select `v_work`.`周` AS `周`,`v_work`.`月份` AS `月份`,`v_work`.`team` AS `team`,sum(`v_work`.`hours`) AS `ITSM花费时数`,`v_work`.`uname` AS `人员` from `v_work` where (`v_work`.`工作类型` = 'ITSM') group by `v_work`.`周`,`v_work`.`月份`,`v_work`.`team`,`v_work`.`uname`;
CREATE VIEW v_work_item (月份, 周, 团队, 处理人, 处理内容, 开始时间, 结束时间, 处理时长, 处理单号, 问题大类, 工单标题) AS select date_format(`i`.`optime1`,'%Y%m') AS `月份`,week(`i`.`optime1`,0) AS `周`,`u`.`team` AS `团队`,`u`.`uname` AS `处理人`,`i`.`op` AS `处理内容`,`i`.`optime0` AS `开始时间`,`i`.`optime1` AS `结束时间`,`i`.`hours` AS `处理时长`,`i`.`bizKey` AS `处理单号`,`t`.`问题大类` AS `问题大类`,`t`.`工单标题` AS `工单标题` from ((`t_item_time` `i` join `t_team` `u` on((`i`.`user1` = `u`.`operateUserName`))) left join `v_trend` `t` on((`i`.`bizKey` = `t`.`工单编号`)));
--/

3 定位属性、计算工作时间及SLA判断

获取到详细的数据后,接下来需要进行关键的数据处理和分析工作。

  1. 定位属性:通过预先设定的规则和关键词匹配算法,对抓取到的服务请求内容进行分析,自动确定服务票的属性。例如,当请求中包含与权限相关的特定词汇(如"权限申请""访问权限"等),则判定为正常的权限申请。
  2. 计算工作时间:根据每个节点的进入时间和离开时间,计算整个服务处理过程的累计工作时间。考虑到可能存在跨天、跨团队的情况,代码需要对时间进行精确计算和累加。以下是使用Python实现计算工作时间的示例:

SQL存储过程和函数的简要概述:

1. 函数 f_duration

描述:计算两个日期时间之间的工作时长,扣除周末和节假日。

主要功能

  • 接受两个参数 t0t1(开始时间和结束时间)。
  • 处理开始和结束时间是否在工作时间内(9:00-18:00),若不在则调整到最近的工作时间。
  • 计算同一天内两者的时间差,若跨天则累加中间工作日的工作时间。
  • 扣除周末和节假日的天数,计算总的工作小时数。
  • 返回总的工作时长(以小时为单位)。

应用场景:用于计算员工在两个时间点之间的实际工作时间,常用于考勤、工时统计等。

sql 复制代码
CREATE DEFINER=`root`@`%` FUNCTION `itsm`.`f_duration`(`t0` datetime,`t1` datetime) RETURNS float
BEGIN
	#Routine body goes here...
	
DECLARE d0 VARCHAR(8) ;
DECLARE d1 VARCHAR(8) ;
-- 转换 日 计算中间的假日数
-- 开始日的 23:59:59
DECLARE d09 datetime;  
 -- 结束日的 0:0:0
DECLARE d10 datetime;  
DECLARE duration float default 0;
DECLARE dur0 float default 0 ;
DECLARE t0900 datetime;
DECLARE t11800 datetime;
DECLARE t_from datetime default t0;
DECLARE t_end datetime default t1;
DECLARE h1 varchar(2);
DECLARE h0 varchar(2);
DECLARE vh int default 0;
DECLARE vdays1 int default 0;
DECLARE vdaysh int default 0;
select date_format(t0,'%H') into h0;
select date_format(t1,'%H') into h1;
-- INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('h1:',h1));
select date_format(t0,'%Y%m%d') into d0;
select date_format(t1,'%Y%m%d') into d1;

SELECT count(1) into vh from t_holiday where ID = d0;

-- 处理 早于9:00  晚于18:00 的工作时间

if  h0 < '09' then
    select CONCAT(date_format(t0,'%Y-%m-%d'), ' ' , '9:0:0') into t_from ;
end if;
if  h0 >= '18' then 
    select CONCAT(date_format(t0,'%Y-%m-%d'), ' ' , '18:0:0') into t_from ;  
end if;

if  h1 < '09' then
    select CONCAT(date_format(t1,'%Y-%m-%d'), ' ' , '9:0:0') into t_end ;
end if;
if  h1 >= '18' then 
    select CONCAT(date_format(t1,'%Y-%m-%d'), ' ' , '18:0:0') into t_end ;  
end if;

-- INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('T FROM:',date_format(t_from,'%Y-%m-%d %T')));
-- INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('T END:',date_format(t_end,'%Y-%m-%d %T')));
-- INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('d0:',d0));
-- INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('d1:',d1));
-- INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('vh:',vh));
if d0 = d1 and vh = 0 then 
 SELECT timestampdiff(second , t_from , t_end ) into duration;
--  INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('duration:',duration));
else 

-- t0 时间
  if vh = 0 then
   SELECT timestampdiff(second , t_from , CONCAT(date_format(t0,'%Y-%m-%d'), ' ' , '18:0:0') ) into dur0;
    set duration = duration + dur0;
  end if;
-- t1 时间  

  SELECT count(1) into vh from t_holiday where ID = d1;
--   INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('vh of t1:',vh));
   if vh = 0 then
    SELECT timestampdiff(second , CONCAT(date_format(t1,'%Y-%m-%d'), ' ' , '09:00:00'), t_end ) into dur0;
--     INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT(date_format(t1,'%Y-%m-%d'), ' ' , '09:0:0'));   
--     INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('T END:',date_format(t_end,'%Y-%m-%d %T')));
--     INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('T dur0:',dur0));
   set duration = duration + dur0;
    INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('T duration:',duration));
  end if; 
-- 中间时间
  SELECT timestampdiff(day, CONCAT(date_format(t0,'%Y-%m-%d'), ' ' , '23:59:59'),CONCAT(date_format(t1,'%Y-%m-%d'), ' ' , '0:0:0')) into vdays1;
--     INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('vdays1:',vdays1));
  SELECT count(1) into vdaysh from t_holiday where ID > d0 and ID < d1;
--     INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('vdaysh:',vdaysh));  
  set duration = duration + 3600 *9* (vdays1 - vdaysh); 
  
end if;
	RETURN duration;
END

补充说明

函数 f_duration 的功能说明

函数 f_duration 的主要功能是计算两个时间点之间的工作时长(以小时为单位),并排除非工作时间(如早于 9:00 或晚于 18:00 的时间)以及节假日的影响。


函数的输入参数
  • t0:开始时间,类型为 datetime
  • t1:结束时间,类型为 datetime

函数的返回值
  • 返回值为 float 类型,表示两个时间点之间的工作时长(单位为小时)。

函数的主要逻辑
1. 定义变量

函数定义了多个变量,用于存储中间计算结果和时间点:

  • d0d1:将 t0t1 转换为日期格式(YYYYMMDD),用于判断是否为同一天。
  • d09d10:分别表示开始时间的 23:59:59 和结束时间的 0:0:0,用于计算中间天数。
  • duration:最终的工作时长(单位为小时)。
  • dur0:临时变量,用于存储部分时间段的时长。
  • t_fromt_end:调整后的开始时间和结束时间,确保在有效工作时间内(9:00-18:00)。
  • h0h1:分别表示 t0t1 的小时部分(HH)。
  • vh:表示某天是否为节假日(通过查询 t_holiday 表判断)。
  • vdays1:计算两个日期之间的完整天数。
  • vdaysh:计算两个日期之间的节假日天数。

2. 提取时间信息
复制代码

sql

SELECT date_format(t0, '%H') INTO h0;
SELECT date_format(t1, '%H') INTO h1;
SELECT date_format(t0, '%Y%m%d') INTO d0;
SELECT date_format(t1, '%Y%m%d') INTO d1;
  • 使用 date_format 提取 t0t1 的小时部分(h0h1)和日期部分(d0d1)。

3. 调整开始时间和结束时间

函数会根据工单的开始时间和结束时间是否在工作时间内(9:00-18:00),调整 t_fromt_end

  • 如果 t0 的小时小于 9,则将 t_from 设置为当天的 9:00:00。
  • 如果 t0 的小时大于等于 18,则将 t_from 设置为当天的 18:00:00。
  • 如果 t1 的小时小于 9,则将 t_end 设置为当天的 9:00:00。
  • 如果 t1 的小时大于等于 18,则将 t_end 设置为当天的 18:00:00。
复制代码

sql

IF h0 < '09' THEN
    SELECT CONCAT(date_format(t0, '%Y-%m-%d'), ' ', '9:0:0') INTO t_from;
END IF;
IF h0 >= '18' THEN
    SELECT CONCAT(date_format(t0, '%Y-%m-%d'), ' ', '18:0:0') INTO t_from;
END IF;
IF h1 < '09' THEN
    SELECT CONCAT(date_format(t1, '%Y-%m-%d'), ' ', '9:0:0') INTO t_end;
END IF;
IF h1 >= '18' THEN
    SELECT CONCAT(date_format(t1, '%Y-%m-%d'), ' ', '18:0:0') INTO t_end;
END IF;

4. 计算同一天内的工作时长

如果 t0t1 在同一天,并且都不是节假日,则直接计算两个时间点之间的秒数差:

复制代码

sql

IF d0 = d1 AND vh = 0 THEN
    SELECT TIMESTAMPDIFF(SECOND, t_from, t_end) INTO duration;

5. 计算跨天的工作时长

如果 t0t1 跨天,则分三部分计算工作时长:

  1. 开始时间的有效工作时长

    • 如果 t0 不是节假日,计算从 t_from 到当天 18:00 的秒数差。
    复制代码

    sql

    IF vh = 0 THEN
        SELECT TIMESTAMPDIFF(SECOND, t_from, CONCAT(date_format(t0, '%Y-%m-%d'), ' ', '18:0:0')) INTO dur0;
        SET duration = duration + dur0;
    END IF;
    
  2. 结束时间的有效工作时长

    • 如果 t1 不是节假日,计算从当天 9:00 到 t_end 的秒数差。
    复制代码

    sql

    IF vh = 0 THEN
        SELECT TIMESTAMPDIFF(SECOND, CONCAT(date_format(t1, '%Y-%m-%d'), ' ', '09:00:00'), t_end) INTO dur0;
        SET duration = duration + dur0;
    END IF;
    
  3. 中间完整天数的工作时长

    • 计算两个日期之间的完整天数(vdays1)。
    • 计算两个日期之间的节假日天数(vdaysh)。
    • 每天的工作时长为 9 小时(9 * 3600 秒),减去节假日的天数。
    复制代码

    sql

    SELECT TIMESTAMPDIFF(DAY, CONCAT(date_format(t0, '%Y-%m-%d'), ' ', '23:59:59'), CONCAT(date_format(t1, '%Y-%m-%d'), ' ', '0:0:0')) INTO vdays1;
    SELECT COUNT(1) INTO vdaysh FROM t_holiday WHERE ID > d0 AND ID < d1;
    SET duration = duration + 3600 * 9 * (vdays1 - vdaysh);
    

6. 返回结果

最终返回计算的工作时长(单位为小时):

复制代码

sql

RETURN duration;

2. 存储过程 item_time

描述:处理和记录工单的操作时间及相关信息。

主要功能

  • 遍历 t_main_history 表中特定 bizKey 的历史记录。
  • 根据操作内容(如创建、领取、处理、转派、关闭等)设置相应的操作类型。
  • 计算每次操作的时间差,并判断是否超期。
  • 将处理结果插入或更新到 t_item_time 表中,记录每个工单的操作时间、操作人、耗时等信息。

应用场景:用于跟踪和分析工单的处理过程,记录每个操作的时间点和耗时,便于后续的绩效评估和流程优化。

sql 复制代码
CREATE DEFINER=`root`@`%` PROCEDURE `itsm`.`item_time`(inbiz VARCHAR(255))
BEGIN
-- 宣告变数
DECLARE vid VARCHAR(255) ;
DECLARE ibiz int;
DECLARE vbizKey VARCHAR(255) ;
DECLARE vuser0 VARCHAR(255) ;
DECLARE vuser1 VARCHAR(255) ;
DECLARE vop varchar(64) ;
DECLARE vteam varchar(16) ;
DECLARE voptime1 DATETIME ;
DECLARE voptime0 DATETIME ;
DECLARE vcontent text;
DECLARE vseconds float ;
DECLARE vhours float ;
DECLARE vdays float ;
DECLARE done int default 0;
DECLARE doneh int default 0;
DECLARE iupdate int;
DECLARE i1 int;
DECLARE iop int;
DECLARE icount int;
DECLARE vops1 text default '通过 WEB_FORM 创建了工单';
DECLARE vops2 text default ' 领取了工单 ';
DECLARE vops5 text default '处理' ; --  '处理提交了工单(一级人员处理)';
DECLARE vops4 text default '回退至 申请人建单 阶段';
DECLARE vops3 text default '将工单转派给了';
DECLARE vops6 text default '在用户确认';
DECLARE vops7 text default '关闭了工单';
DECLARE vop1 varchar(64) default '创建';
DECLARE vop2 varchar(64) default '领取';
DECLARE vop5 varchar(64) default '处理';
DECLARE vop4 varchar(64) default '回退';
DECLARE vop3 varchar(64) default '转派';
DECLARE vop6 varchar(64) default '确认';
DECLARE vop7 varchar(64) default '关闭';
DECLARE ioverdue int;


DECLARE C1 CURSOR FOR 
 SELECT id, bizKey, operateUserName,  content, operatedTime FROM t_main_history where bizKey = inbiz order by operatedtime;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;   -- 溢出处理


    
OPEN C1; 
set i1 = 0;
LOOPC1: LOOP
   set i1 = i1 + 1;
   INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('done:',done));     
    FETCH c1 into vid, vbizKey, vuser1,  vcontent, voptime1;
	IF done THEN
		LEAVE loopc1; -- 跳出游标循环
	END IF;    
	-- 第一笔提前赋值
	if i1 = 1 then 
            set vuser0 = vuser1;
            set voptime0 = voptime1;    
        end if;
      -- 判断 team 
--      set vteam = '';
--      select team into vteam from t_team where operateUserName = trim(vuser1)  ;
      INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('i1:',i1));     
      INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('user:',vuser1));
      INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('team :',vteam));            
        -- 计算时间差 function  f-duration 已扣除假日时间
 --       SELECT  timestampdiff(second , voptime0, voptime1) into vseconds;
        SELECT f_duration(voptime0, voptime1) into vseconds;
        SET vhours = vseconds / 3600;
        SET vdays = vhours / 9;
        if vdays > 3 then
        set ioverdue = 1 ;
        else 
        set ioverdue = 0;
        end if;
        
    -- 判断 content 赋值给 vop        
        SELECT locate( vops1, vcontent ) into   iop;
        if iop > 0 then 
                set vop = vop1;
        else 
            SELECT locate( vops2, vcontent ) into  iop;    
            if iop > 0 then 
                set vop = vop2;
            else
                    SELECT locate( vops3, vcontent ) into  iop;    
                    if iop > 0 then 
                        set vop = vop3;      
                    else
                            SELECT locate( vops4, vcontent ) into  iop;    
                            if iop > 0 then 
                                set vop = vop4;
	                   else
                                    SELECT locate( vops5, vcontent ) into  iop;    
                                    if iop > 0 then 
                                        set vop = vop5;
                                   else
                                        SELECT locate( vops6, vcontent ) into  iop;    
                                                if iop > 0 then 
                                                 set vop = vop6;
                                                else  
                                                SELECT locate( vops7, vcontent ) into  iop;    
                                                        if iop > 0 then 
                                                         set vop = vop7;
                                                        end if; 
                                                end if;
                                   end if;	                   
                           end if;                          
                   end if;    
            end if;    
        end if;


    
    select count(vid) into icount from t_item_time where id = vid;
    if icount = 0 then
        INSERT INTO t_item_time (id, bizKey, user0, user1, op, optime0, optime1, seconds, hours, days, content,overdue) VALUES (vid, vbizkey, vuser0, vuser1, vop, voptime0 ,voptime1, vseconds, vhours, vdays, vcontent, ioverdue);
    else
        UPDATE t_item_time SET id = vid, bizKey = vbizkey, user0 =vuser0, user1 = vuser1, op = vop, optime0 = voptime0, optime1 = voptime1, seconds = vseconds, hours = vhours, days = vdays , content = vcontent, overdue = ioverdue WHERE id = vid;
    end if;
    set vuser0 = vuser1;
    set voptime0 = voptime1; 
    set vop = '';
END LOOP LOOPC1;   
CLOSE C1;


END

补充说明

存储过程 item_time 的功能说明

存储过程 item_time 的主要功能是处理工单的操作历史记录(存储在表 t_main_history 中),并根据操作记录计算每个操作的时间差、判断操作类型、标记是否超期等,最终将结果存储到表 t_item_time 中。


存储过程的主要逻辑
1. 定义变量

存储过程中定义了多个变量,用于存储中间计算结果和操作记录的相关信息:

  • 工单相关变量
    • vid:当前记录的 ID。
    • vbizKey:工单的业务键(bizKey),用于标识工单。
    • vuser0vuser1:当前记录和上一条记录的操作用户。
    • vop:当前操作的类型(如"创建"、"领取"、"处理"等)。
    • voptime0voptime1:当前记录和上一条记录的操作时间。
    • vcontent:操作的具体内容。
  • 时间相关变量
    • vseconds:两个操作之间的时间差(单位为秒)。
    • vhours:时间差转换为小时。
    • vdays:时间差转换为天。
    • ioverdue:标记是否超期(1 表示超期,0 表示未超期)。
  • 操作类型相关变量
    • vops1vops7:定义了不同操作的关键词(如"创建"、"领取"等)。
    • vop1vop7:与 vops1vops7 对应的操作类型名称。
  • 其他变量
    • done:游标结束标志。
    • i1:循环计数器。
    • icount:判断当前记录是否已存在于 t_item_time 表中。
    • ioverdue:标记是否超期。

2. 游标定义
复制代码

sql

DECLARE C1 CURSOR FOR 
SELECT id, bizKey, operateUserName, content, operatedTime 
FROM t_main_history 
WHERE bizKey = inbiz 
ORDER BY operatedtime;
  • 游标 C1 用于遍历表 t_main_history 中与指定工单(inbiz)相关的操作记录,按照操作时间(operatedTime)升序排列。

3. 初始化和游标循环
复制代码

sql

OPEN C1;
SET i1 = 0;
LOOPC1: LOOP
    SET i1 = i1 + 1;
    FETCH C1 INTO vid, vbizKey, vuser1, vcontent, voptime1;
    IF done THEN
        LEAVE LOOPC1; -- 跳出游标循环
    END IF;
  • 打开游标 C1,逐条读取操作记录。
  • 如果游标到达末尾(done = 1),则退出循环。

4. 初始化第一条记录
复制代码

sql

IF i1 = 1 THEN 
    SET vuser0 = vuser1;
    SET voptime0 = voptime1;    
END IF;
  • 对于第一条记录,初始化上一条记录的用户和时间信息。

5. 计算时间差
复制代码

sql

SELECT f_duration(voptime0, voptime1) INTO vseconds;
SET vhours = vseconds / 3600;
SET vdays = vhours / 9;
  • 使用函数 f_duration 计算两个操作之间的时间差(扣除非工作时间和节假日),返回秒数。
  • 将秒数转换为小时和天。

6. 判断是否超期
复制代码

sql

IF vdays > 3 THEN
    SET ioverdue = 1;
ELSE 
    SET ioverdue = 0;
END IF;
  • 如果时间差大于 3 天,则标记为超期(ioverdue = 1),否则标记为未超期(ioverdue = 0)。

7. 判断操作类型
复制代码

sql

SELECT LOCATE(vops1, vcontent) INTO iop;
IF iop > 0 THEN 
    SET vop = vop1;
ELSE 
    SELECT LOCATE(vops2, vcontent) INTO iop;
    IF iop > 0 THEN 
        SET vop = vop2;
    -- ... 类似的判断逻辑 ...
    END IF;
END IF;
  • 使用 LOCATE 函数在操作内容(vcontent)中查找关键词(如"创建"、"领取"等),以确定操作类型。
  • 如果找到关键词,则将对应的操作类型名称(如"创建"、"领取"等)赋值给变量 vop

8. 检查记录是否已存在
复制代码

sql

SELECT COUNT(vid) INTO icount 
FROM t_item_time 
WHERE id = vid;
  • 查询表 t_item_time,判断当前记录是否已存在。

9. 插入或更新记录
复制代码

sql

IF icount = 0 THEN
    INSERT INTO t_item_time (...) 
    VALUES (vid, vbizkey, vuser0, vuser1, vop, voptime0, voptime1, vseconds, vhours, vdays, vcontent, ioverdue);
ELSE
    UPDATE t_item_time 
    SET ... 
    WHERE id = vid;
END IF;
  • 如果当前记录不存在于 t_item_time 表中,则插入一条新记录。
  • 如果当前记录已存在,则更新该记录。

10. 更新状态变量
复制代码

sql

SET vuser0 = vuser1;
SET voptime0 = voptime1; 
SET vop = '';
  • 更新上一条记录的用户和时间信息,为下一条记录的处理做好准备。

存储过程的目标
  1. 解析工单操作历史

    • 遍历工单的操作历史记录(t_main_history 表),提取每条记录的操作时间、操作用户和操作内容。
  2. 计算时间差

    • 使用函数 f_duration 计算相邻两条操作记录之间的时间差,扣除非工作时间和节假日。
  3. 判断操作类型

    • 根据操作内容中的关键词(如"创建"、"领取"等),确定每条记录的操作类型。
  4. 标记超期记录

    • 如果相邻两条操作记录之间的时间差超过 3 天,则标记为超期。
  5. 存储结果

    • 将解析后的操作记录存储到表 t_item_time 中,便于后续查询和分析。

3. 存储过程 p_checklist

描述:管理和更新检查清单的执行状态。

主要功能

  • 查找所有计划执行时间早于当前时间且状态为"未执行"的检查项。
  • 根据频率(如每天、每月等)计算下一次执行时间,跳过节假日。
  • 更新检查项的状态为"执行中",并在执行后更新为"已执行",记录执行时间。
  • 处理不同频率的检查项,确保按计划执行。

应用场景:用于自动化管理定期任务或检查清单,确保各项任务按时执行并记录执行状态。

4. 存储过程 p_fssc_h

描述 :处理 t_fssc_h_temp 表中的数据,更新或插入到 t_fssc_h 表中,并调用 item_time 处理工单时间。

主要功能

  • 清空临时表 t_fssc_h_temp_distinct 并插入去重后的数据。
  • 遍历 t_fssc_h_temp 中的每条记录,根据 工单编号 判断是插入新记录还是更新现有记录。
  • 如果需要更新且 inupdate 参数为 'x',则调用 item_time 处理工单时间。
  • 更新 t_fssc_h 表中的 原因 字段,并设置 item更新 标志。

应用场景:用于同步和处理临时表中的工单数据,确保主表数据的准确性和完整性,同时记录工单处理时间。

sql 复制代码
CREATE DEFINER=`root`@`%` PROCEDURE `itsm`.`p_fssc_h`(inupdate varchar(2))
BEGIN
	#Routine body goes here...
-- inupdate 如果导入 t_fssc_h 前 已有 history 更新 则 in update 输入 x 会进行 item 更新
DECLARE inbiz VARCHAR(255) ; --  default 'FSSC2023092300001';
DECLARE ibiz int;
DECLARE iupdate int;
DECLARE done int default 0;



DECLARE C0 CURSOR FOR SELECT  工单编号 FROM t_fssc_h_temp;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;   -- 溢出处理	

    -- 先对已存在的临时表t_fssc_h_temp_distinct进行truncate操作,清空表中数据
    TRUNCATE TABLE t_fssc_h_temp_distinct;

    -- 将去重后的数据插入到临时表t_fssc_h_temp_distinct中,按照工单编号分组取每组的一条记录(按创建日期排序取最早的一条)
    -- 先对已存在的临时表t_fssc_h_temp_distinct进行truncate操作,清空表中数据
    TRUNCATE TABLE t_fssc_h_temp_distinct;

    -- 使用SELECT DISTINCT将去重后的数据插入到临时表t_fssc_h_temp_distinct中,以工单编号等字段整体去重
    INSERT INTO t_fssc_h_temp_distinct
    SELECT DISTINCT
        创建日期,
        工单编号,
        工单标题,
        当前节点,
        优先级,
        案件状态,
        建单日期,
        提报人,
        所在公司代码,
        所在公司名称,
        更新人,
        支持团队,
        消息处理人,
        流程名称,
        类别2,
        类别3N,
        共享单据号,
        解决方案,
        问题分类,
        问题类别二级,
        单据响应状态,
        单据解决状态
    FROM t_fssc_h_temp;

    -- 根据传入的参数决定是否替换原表数据
        -- 先删除原表数据
        DELETE FROM t_fssc_h_temp;
        -- 把临时表数据插入回原表
        INSERT INTO t_fssc_h_temp SELECT * FROM t_fssc_h_temp_distinct;

	

OPEN C0;
LOOPC0: LOOP
    FETCH  C0 into  inbiz;
	IF done THEN
		LEAVE LOOPC0; -- 跳出游标循环
	END IF;    
    select count(1) into ibiz from t_fssc_h where 工单编号 = inbiz  LIMIT 1;
    if ibiz = 0 then
    INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('inbiz65:',inbiz));    
     INSERT INTO t_fssc_h (创建日期, 工单编号, 工单标题, 当前节点, 优先级, 案件状态, 建单日期, 提报人, 所在公司代码, 所在公司名称, 更新人, 支持团队, 消息处理人, 流程名称, 类别2, 类别3N, 共享单据号, 解决方案, 问题分类, 问题类别二级, 单据响应状态, 单据解决状态,item更新) 
     SELECT 创建日期, 工单编号, 工单标题, 当前节点, 优先级, 案件状态, 建单日期, 提报人, 所在公司代码, 所在公司名称, 更新人, 支持团队, 消息处理人, 流程名称, 类别2, 类别3N, 共享单据号, 解决方案, 问题分类, 问题类别二级, 单据响应状态, 单据解决状态,0 FROM t_fssc_h_temp where  工单编号 = inbiz;   
    else
    update t_fssc_h  a join t_fssc_h_temp b on a.工单编号 = b.工单编号 set 
        a.当前节点 = b.当前节点,
        a.优先级 = b.优先级,
        a.案件状态 = b.案件状态,
        a.建单日期 = b.建单日期,
        a.提报人 = b.提报人,
        a.所在公司代码 = b.所在公司代码,
        a.所在公司名称 = b.所在公司名称,
        a.更新人 = b.更新人,
        a.支持团队 = b.支持团队,
        a.消息处理人 = b.消息处理人,
        a.流程名称 = b.流程名称,
        a.类别2 = b.类别2,
        a.类别3N = b.类别3N,
        a.共享单据号 = b.共享单据号,
        a.解决方案 = b.解决方案,
        a.问题分类 = b.问题分类,
        a.问题类别二级 = b.问题类别二级,
        a.单据响应状态 = b.单据响应状态,
        a.单据解决状态 = b.单据解决状态
     where b.工单编号 = inbiz and a.案件状态 not in( '已完成', '已关闭');
    end if;
select  item更新 into iupdate from t_fssc_h where 工单编号 = inbiz  LIMIT 1;
INSERT INTO t_remark (rtime, remark) VALUES ( now(),  CONCAT('inbiz92:',inbiz)) ;    
if  iupdate = 0 and inupdate = 'x' then    
  call item_time(inbiz);
end if;
END LOOP LOOPC0;   
CLOSE C0;

UPDATE t_fssc_h SET  原因 = SUBSTRING_INDEX(SUBSTRING_INDEX(解决方案,'原因:', -1 ), '\n',1) 
where 解决方案 like  '原因%' and 案件状态 in( '已完成', '已关闭') and item更新 != 1;

update t_fssc_h set  item更新 = 1 where  案件状态 in( '已完成', '已关闭') and item更新 != 1;

if inupdate = 'x' then
DELETE FROM t_fssc_h_temp;	
end if;



END

下是对存储过程 p_fssc_h 的详细补充说明和优化建议:


存储过程功能概述
  1. 清空和去重临时表数据

    • 清空临时表 t_fssc_h_temp_distinct
    • t_fssc_h_temp 中的数据去重后插入到 t_fssc_h_temp_distinct 中。
  2. 同步数据到主表

    • 遍历 t_fssc_h_temp 中的每条记录,判断是否需要插入新记录或更新现有记录。
    • 如果需要更新且参数 inupdate'x',则调用 item_time 处理工单时间。
  3. 更新主表字段

    • 更新 t_fssc_h 表中的 原因 字段。
    • 设置 item更新 标志。
  4. 清理临时数据

    • 如果 inupdate'x',则清空 t_fssc_h_temp

存储过程详细说明
1. 清空和去重临时表数据
复制代码

sql

TRUNCATE TABLE t_fssc_h_temp_distinct;

INSERT INTO t_fssc_h_temp_distinct
SELECT DISTINCT
    创建日期,
    工单编号,
    工单标题,
    当前节点,
    优先级,
    案件状态,
    建单日期,
    提报人,
    所在公司代码,
    所在公司名称,
    更新人,
    支持团队,
    消息处理人,
    流程名称,
    类别2,
    类别3N,
    共享单据号,
    解决方案,
    问题分类,
    问题类别二级,
    单据响应状态,
    单据解决状态
FROM t_fssc_h_temp;
  • 使用 TRUNCATE 清空临时表 t_fssc_h_temp_distinct
  • 使用 SELECT DISTINCT 插入去重数据,确保每条记录的唯一性。
2. 同步数据到主表
复制代码

sql

OPEN C0;
LOOPC0: LOOP
    FETCH C0 INTO inbiz;
    IF done THEN
        LEAVE LOOPC0;
    END IF;

    -- 检查工单编号是否已存在
    SELECT COUNT(1) INTO ibiz FROM t_fssc_h WHERE 工单编号 = inbiz LIMIT 1;

    IF ibiz = 0 THEN
        -- 插入新记录
        INSERT INTO t_fssc_h (...)
        SELECT ... FROM t_fssc_h_temp WHERE 工单编号 = inbiz;
    ELSE
        -- 更新现有记录
        UPDATE t_fssc_h a
        JOIN t_fssc_h_temp b ON a.工单编号 = b.工单编号
        SET ...
        WHERE b.工单编号 = inbiz AND a.案件状态 NOT IN ('已完成', '已关闭');
    END IF;

    -- 调用 item_time 处理工单时间
    IF iupdate = 0 AND inupdate = 'x' THEN
        CALL item_time(inbiz);
    END IF;
END LOOP;
CLOSE C0;
  • 使用游标遍历 t_fssc_h_temp 中的每条记录。
  • 根据工单编号判断是插入新记录还是更新现有记录。
  • 如果需要更新且 inupdate'x',则调用 item_time 处理工单时间。
3. 更新主表字段
复制代码

sql

UPDATE t_fssc_h
SET 原因 = SUBSTRING_INDEX(SUBSTRING_INDEX(解决方案, '原因:', -1), '\n', 1)
WHERE 解决方案 LIKE '原因%' 
  AND 案件状态 IN ('已完成', '已关闭') 
  AND item更新 != 1;

UPDATE t_fssc_h
SET item更新 = 1
WHERE 案件状态 IN ('已完成', '已关闭') 
  AND item更新 != 1;
  • 更新 原因 字段,提取 解决方案 中的"原因"部分。
  • 设置 item更新 标志为 1,表示已处理。
4. 清理临时数据
复制代码

sql

IF inupdate = 'x' THEN
    DELETE FROM t_fssc_h_temp;
END IF;
  • 如果 inupdate'x',则清空 t_fssc_h_temp

5. 存储过程 p_fssc_mis

描述 :将 t_fssc_h 表中缺少 itemtime 记录的工单插入到 t_fssc_mis 表中。

主要功能

  • 清空目标表 itsm.t_fssc_mis
  • 插入 t_fssc_h 表中存在但 t_item_time 表中不存在对应记录的工单编号,且工单编号以 'FSSC' 开头。

应用场景:用于识别和记录那些尚未有详细时间记录的工单,便于后续跟踪和管理。

6. 存储过程 p_sla

描述 :处理和更新SLA(服务水平协议)相关的数据,主要涉及 t_slat_sla0 表。

主要功能

  • 清空目标表 itsm.t_sla0itsm.t_sla
  • 插入 t_sla0 中相关的SLA数据。
  • 遍历 t_sla0 的数据,根据工单编号和团队等信息,插入或更新 t_sla 表中的记录,计算领取时间和处理时间。
  • 记录相关操作的备注信息。

应用场景:用于维护和更新服务水平协议相关的指标和数据,确保服务质量和性能监控。

sql 复制代码
CREATE DEFINER=`root`@`%` PROCEDURE `itsm`.`p_sla`()
BEGIN
	#Routine body goes here...

declare v_工单编号  VARCHAR(255) ;
declare v_bill  VARCHAR(255) ;
declare v_工单编号o  VARCHAR(255) ;
declare v_round int default 0;

declare v_optime0 datetime;
declare v_optime0o datetime;
declare v_optime1 datetime;
declare v_optime1o datetime;
declare v_optime2 datetime;
declare v_optime2o datetime;

declare v_op1领取人 varchar(255);
declare v_op2处理人 varchar(255);     
declare v_领取耗时  float;
declare v_处理时间 float;
declare v_处理时间l float;
declare v_处理时间c float;


declare v_user0 varchar(255);
declare v_user0o varchar(255);
declare v_user1 varchar(255);
declare v_领取人 varchar(255);
declare v_处理人 varchar(255);
declare v_team varchar(16);
declare v_teamo varchar(16);
declare v_days float;
DECLARE  done int default 0;
declare new_bill int default 0;
declare new_team int default 0;
declare v_check int;
declare v_cnt int;

declare C1 cursor for select
        工单编号,  user0, user1, optime0, optime1, days, ifnull(team,'') FROM t_sla0
        order by 工单编号,optime1 asc;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; 


TRUNCATE TABLE itsm.t_sla0;
INSERT INTO t_sla0 (工单编号, user0, user1, optime0, optime1, days, team)     
select
        工单编号,  user0, user1, optime0, optime1, days, team FROM v_sla
        where user1 is not null 
        order by 工单编号,optime1;
        
TRUNCATE TABLE itsm.t_sla;
TRUNCATE TABLE itsm.t_remark;
set v_工单编号o = '';
set v_teamo = '';

OPEN C1; 
LOOPC1: LOOP

FETCH C1 into v_工单编号,  v_user0, v_user1,  v_optime0, v_optime1, v_days, v_team;
        IF done THEN
                LEAVE loopc1; 
        END IF;     	

if v_工单编号 != v_工单编号o   then 
    set v_round = 1;        
    set v_cnt = 0;
        if(not exists(select *  from t_sla where 工单编号 = v_工单编号o and round = v_round)) then 
        INSERT INTO t_sla (工单编号, round, optime0, optime1, optime2, team, user0, op1领取人, op2处理人, 领取耗时, 处理时间) 
        VALUES (v_工单编号, v_round, v_optime0, v_optime1, v_optime1, v_team,v_user0 ,v_user1, v_user1,  v_days, v_days);
        end if;      
    set v_user0o = v_user0;     
end if;        

if v_工单编号 = v_工单编号o and v_team != v_teamo  and ( v_teamo  = '' )  then 
    set v_cnt = v_cnt +1;
    if v_cnt > 1 then 
    set v_round = v_round + 1;
    end if;
    select count(1) into v_check from t_sla where 工单编号 = v_工单编号 and round = v_round ;
    INSERT INTO t_remark (rtime, remark) VALUES (v_optime1,  CONCAT( 'case 2 v_工单编:',v_工单编号,' v_team:', v_team));     
    if v_check = 0  then
    INSERT INTO t_sla (工单编号, round, optime0, optime1, optime2, team, user0, op1领取人, op2处理人, 领取耗时, 处理时间) 
    VALUES (v_工单编号, v_round, v_optime0, v_optime1, v_optime1, v_team,v_user0o ,v_user1, v_user1,  v_days, v_days);
    end if;
    if v_check != 0 and v_team != ''  then 
    UPDATE t_sla SET  optime1 = v_optime1, optime2 = v_optime1, team = v_team, op1领取人 = v_user1, op2处理人 = v_user1, 领取耗时 = v_days, 处理时间 = v_days
    WHERE 工单编号 = v_工单编号o and round = v_round ;
    end if;
    set v_处理时间l = v_days;
end if;     

if v_工单编号 = v_工单编号o and v_team != v_teamo  and v_teamo != '' and v_team != '' then 
    set v_round = v_round + 1;
    select count(1) into v_check from t_sla where 工单编号 = v_工单编号o and round = v_round ;
    if v_check = 0  then
    INSERT INTO t_sla (工单编号, round, optime0, optime1, optime2, team, user0, op1领取人, op2处理人, 领取耗时, 处理时间) 
    VALUES (v_工单编号, v_round, v_optime0, v_optime1, v_optime1, v_team,v_user0o ,v_user1, v_user1,  v_days, v_days);
    else  
    UPDATE t_sla SET optime1 = v_optime1, optime2 = v_optime1, team = v_team, op1领取人 = v_user1, op2处理人 = v_user1, 领取耗时 = v_days, 处理时间 = v_days
    WHERE 工单编号 = v_工单编号o and round = v_round ;
    end if;
    set v_处理时间l = v_days;
end if;   

if v_工单编号 = v_工单编号o and v_team = v_teamo  then 
    select count(1) into v_check from t_sla where 工单编号 = v_工单编号o and round = v_round ;
    if v_check = 0  then
    INSERT INTO t_sla (工单编号, round, optime0, optime1, optime2, team, user0, op1领取人, op2处理人, 领取耗时, 处理时间) 
    VALUES (v_工单编号, v_round, v_optime0, v_optime1, v_optime1, v_team,v_user0o ,v_user1, v_user1,  v_days, v_days);
    else  
    set v_处理时间c = v_days + v_处理时间l;    
    UPDATE t_sla SET   optime2 = v_optime1, op2处理人 = v_user1,  处理时间 = v_处理时间c
    WHERE 工单编号 = v_工单编号o and round = v_round ;
    end if;
    set v_处理时间l = v_处理时间c;
end if;   


    set v_工单编号o = v_工单编号;
    set v_teamo = v_team;	
    if v_工单编号 != v_工单编号o   then 
    set v_user0o = v_user0;
    set v_optime0o = v_optime0 ;    
    end if;    
    
END LOOP LOOPC1;   
CLOSE C1;       




END

补充说明:

存储过程 p_sla 的功能说明

存储过程 p_sla 的主要功能是处理工单的服务水平协议(SLA)数据,计算工单的处理时间、领取时间等信息,并将结果存储到 t_slat_remark 表中。以下是对存储过程的详细说明:


存储过程的主要逻辑
1. 定义变量

存储过程中定义了多个变量,用于存储工单的相关信息和中间计算结果:

  • 工单相关变量
    • v_工单编号:当前处理的工单编号。
    • v_工单编号o:上一条记录的工单编号,用于比较当前记录和上一条记录是否属于同一个工单。
  • 用户相关变量
    • v_user0v_user0o:工单的初始用户信息。
    • v_user1:工单的处理人信息。
  • 时间相关变量
    • v_optime0v_optime1:工单的关键时间点(如领取时间、处理时间)。
    • v_days:工单的处理天数。
    • v_领取耗时v_处理时间:工单的领取时间和处理时间的计算结果。
  • 团队相关变量
    • v_teamv_teamo:工单的团队信息,用于判断是否发生了团队变更。
  • 其他变量
    • v_round:记录当前工单的处理轮次。
    • v_cnt:记录团队变更的次数。
    • done:游标结束标志。

2. 游标定义
复制代码

sql

DECLARE C1 CURSOR FOR 
SELECT 工单编号, user0, user1, optime0, optime1, days, IFNULL(team, '') 
FROM t_sla0
ORDER BY 工单编号, optime1 ASC;
  • 游标 C1 用于遍历 t_sla0 表中的工单数据,按照 工单编号optime1 排序。
  • 数据来源是临时表 t_sla0,其中包含工单的基本信息和时间点。

3. 初始化和数据准备
复制代码

sql

TRUNCATE TABLE itsm.t_sla0;
INSERT INTO t_sla0 (工单编号, user0, user1, optime0, optime1, days, team)     
SELECT 工单编号, user0, user1, optime0, optime1, days, team 
FROM v_sla
WHERE user1 IS NOT NULL 
ORDER BY 工单编号, optime1;

TRUNCATE TABLE itsm.t_sla;
TRUNCATE TABLE itsm.t_remark;
  • 清空临时表 t_sla0,并从视图 v_sla 中插入数据到 t_sla0
  • 清空目标表 t_sla 和日志表 t_remark,为后续计算做好准备。

4. 游标循环处理
复制代码

sql

OPEN C1;
LOOPC1: LOOP
    FETCH C1 INTO v_工单编号, v_user0, v_user1, v_optime0, v_optime1, v_days, v_team;
    IF done THEN
        LEAVE LOOPC1;
    END IF;
  • 打开游标 C1,逐条读取工单数据。
  • 如果游标到达末尾(done = 1),则退出循环。

5. 工单处理逻辑

存储过程根据工单编号、团队信息和时间点的变化,分情况处理工单数据:

​**(1) 新工单处理**
复制代码

sql

IF v_工单编号 != v_工单编号o THEN
    SET v_round = 1;
    ...
  • 如果当前工单编号与上一条记录的工单编号不同,表示这是一个新工单。
  • 初始化处理轮次 v_round = 1,并插入一条初始记录到 t_sla 表。
​**(2) 团队变更处理**
复制代码

sql

IF v_工单编号 = v_工单编号o AND v_team != v_teamo AND (v_teamo = '') THEN
    ...
  • 如果当前工单编号与上一条记录相同,但团队信息发生变化,且上一条记录的团队为空:
    • 增加轮次 v_round
    • 插入或更新 t_sla 表中的记录,记录新的团队信息和时间点。
​**(3) 团队未变更处理**
复制代码

sql

IF v_工单编号 = v_工单编号o AND v_team != v_teamo AND v_teamo != '' THEN
    ...
  • 如果当前工单编号与上一条记录相同,团队信息发生变化,但上一条记录的团队不为空:
    • 增加轮次 v_round
    • 插入或更新 t_sla 表中的记录,记录新的团队信息和时间点。
​**(4) 同团队处理**
复制代码

sql

IF v_工单编号 = v_工单编号o AND v_team = v_teamo THEN
    ...
  • 如果当前工单编号与上一条记录相同,且团队信息未发生变化:
    • 更新 t_sla 表中的记录,累加处理时间。

6. 更新日志表
复制代码

sql

INSERT INTO t_remark (rtime, remark) 
VALUES (v_optime1, CONCAT('case 2 v_工单编:', v_工单编号, ' v_team:', v_team));
  • t_remark 表中插入日志,记录工单的处理过程和相关信息。

7. 更新状态变量
复制代码

sql

SET v_工单编号o = v_工单编号;
SET v_teamo = v_team;
  • 更新状态变量,为下一条记录的处理做好准备。

存储过程的目标

  1. 计算工单的处理时间

    • 根据工单的领取时间(optime0)和处理时间(optime1),计算工单的处理时长。
    • 如果工单经过多个团队处理,累加每个团队的处理时间。
  2. 记录工单的处理轮次

    • 如果工单的团队发生变化,增加处理轮次(round),并记录每一轮的处理信息。
  3. 日志记录

    • t_remark 表中记录工单的处理过程,便于后续审计和分析。
  4. 数据清理和准备

    • 清空临时表和目标表,确保数据的准确性和一致性。

4 以excel利用ODBC从MySQL数据库取数

为了对存储在MySQL数据库中的大量数据进行分析和展示,可以使用Excel 做数据看板,利用ODBC从MySQL中取数。

安装MySQL ODBC驱动程序以连接MySQL数据库涉及几个步骤,包括下载正确的驱动版本、安装驱动以及配置ODBC数据源。以下是详细的步骤指南:

步骤 1:下载 MySQL ODBC 驱动

  1. 访问 MySQL 官方网站

  2. 选择合适的版本

    • 根据你的操作系统(Windows, Linux, macOS)和系统架构(32位或64位),选择对应的MySQL ODBC驱动程序。
    • 对于 Windows 用户,通常会提供两个版本:ANSI 和 Unicode。建议选择 Unicode 版本,除非有特殊需求。
  3. 下载驱动

    • 点击"Download"按钮,并根据提示完成下载过程。

步骤 2:安装 MySQL ODBC 驱动

  1. 运行安装程序

    • 双击下载的 .msi 文件启动安装向导。
  2. 选择安装类型

    • 一般可以选择"Typical"(典型安装)或"Custom"(自定义安装)。如果你不确定,选择"Typical"。
  3. 完成安装

    • 按照屏幕上的指示完成安装过程。完成后,可能需要重启计算机以确保所有更改生效。

步骤 3:配置 ODBC 数据源

在 Windows 上配置 ODBC 数据源
  1. 打开 ODBC 数据源管理器

    • 打开"控制面板",搜索并进入"管理工具",然后选择"ODBC 数据源 (32位)"或"ODBC 数据源 (64位)",具体取决于你安装的驱动版本。
  2. 添加新的数据源

    • 在"用户DSN"、"系统DSN"或"文件DSN"选项卡中,点击"添加"按钮。
  3. 选择 MySQL ODBC 驱动

    • 在弹出的窗口中,找到并选择"MySQL ODBC 8.0 Unicode Driver"(假设你安装的是最新版本),然后点击"完成"。
  4. 配置数据源参数

    • Data Source Name (DSN): 输入一个易于识别的名字。
    • Description: 可选,输入描述信息。
    • TCP/IP Server : 输入MySQL服务器地址(例如 localhost 或服务器IP地址)。
    • Port : 输入MySQL服务器端口,默认是 3306
    • User: 输入数据库用户名。
    • Password: 输入对应的密码。
    • Database: 选择你要连接的数据库名称。
  5. 测试连接

    • 点击"Test"按钮验证连接是否成功。如果一切设置正确,你应该能看到成功的消息。
  6. 保存配置

    • 如果测试连接成功,点击"OK"保存配置并关闭窗口。

步骤 4:使用 ODBC 连接

  • 在应用程序中使用 DSN
    • 现在,你可以在支持ODBC的应用程序中使用刚才创建的DSN进行数据库连接。比如,在Excel中通过ODBC导入数据时,选择相应的DSN即可。

注意事项

  • Visual C++ Redistributable:如前面提到的,某些MySQL ODBC驱动版本可能依赖特定版本的Microsoft Visual C++ Redistributable。确保已安装所需的VC++ Redistributable版本。
  • 防火墙和网络配置:如果MySQL服务器不在本地,请确保防火墙和网络配置允许从客户端到服务器的连接。
  • 权限问题:确保用于连接的数据库账户具有足够的权限执行所需的操作。
相关推荐
hfhf15323 分钟前
电脑突然没有声音的可能原因与应对方法
java
Java资深爱好者24 分钟前
如何在Android中实现SQLite数据库操作
android·数据库·sqlite
宝耶1 小时前
MySQL基础语句
数据库·mysql·oracle
牛牪犇01 小时前
如何搭建一个适配微信小程序,h5,app的uni-app项目
前端·微信小程序·小程序·前端框架
LKAI.1 小时前
MongoDB备份与还原
linux·数据库·mongodb
祈澈菇凉1 小时前
React 中如何实现表单的受控组件?
前端·javascript·react.js
dreams_dream2 小时前
docker启动jenkins,jenkins中调用docker
java·docker·jenkins
计算机-秋大田3 小时前
基于Spring Boot的国产动漫网站的设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·课程设计
站在墙头上3 小时前
java虚拟机(JVM)以及各种参数详解
java·开发语言·jvm
*星星之火*3 小时前
【GPT入门】第11课 FunctionCall调用本地代码入门
java·gpt·openai