MySql 计算服务正常运行时间的查询

MySql Query for calculating Service uptime

我有两个 table。在一个 table 中,我维护服务的开始和结束时间。第二个 table 是跨国的,它包含服务的开始和停止时间(0 表示停止,1 表示开始)。 需要帮助 MySQL 查询一天或特定日期范围内的服务可用性,以小时为单位:

Date      |ServiceId|Available|Not available
06-08-2020|189      | 10      |2
06-08-2020|187      | 8       |4

我的表格如下:

TblStatus

ServiceId|status|Updated_Date
189      |1     |04-08-2020 09:42
189      |0     |04-08-2020 12:29
189      |1     |04-08-2020 12:47
189      |0     |04-08-2020 13:37
189      |1     |04-08-2020 14:16

TblMaster

ServiceId|StartTime|EndTime
189      |09:00:00 |23:59:59
  1. 按服务对数据集进行排序,updated_at asc
  2. 创建变量,您将在其中保存您处理的前一行

您可能需要跟踪: last_row_service_id last_row_status last_row_updated_date

  1. 处理数据集
    #pseudocode
    @SET last_row_service_id := -1;
    @SET last_row_status := -10; #set to -10 so that we wont have -1 or +1 value in first row
    @SET last_row_updated_date :='2020-08-06 00:00:00';
    
    select DATE(updated_date) as 'Date', serviceId as ServiceId,
    
    SUM(IF(@last_row_service_id = serviceId AND @last_row_status - status = 1, 
    
    #check if youre still on the same service and if last_row_status is 1 and current row status is 0
    
    TIME_TO_SEC(updated_date) - TIME_TO_SEC(@last_row_updated_date), 0)) as 'Available', 
    
    #Get elapsed time in seconds, else return 0 seconds
    
    # Do the same to 'Not available'
    
    SUM(IF(@last_row_service_id = serviceId AND @last_row_status - status = -1, 
    
    TIME_TO_SEC(updated_date) - TIME_TO_SEC(@last_row_updated_date), 0)) as 'Not available', 
    
    # change value of pointers
    
    @last_row_service_id := serviceId,
    @last_row_status := status,
    @last_row_updated_date := updated_date
    
    from TblStatus
    #Add your date filter
    group by DATE(updated_date),serviceId

您仍然需要处理超过 23:59:59

的服务正常运行时间

您可以做的是在每天开始时添加 START(状态 1)事件,在每天结束时添加 STOP(状态 0)事件,然后再进行处理。

SELECT Date(TS.Updated_Date) as Updated_Date, TM.ServiceId,
count(case when TS.Status=1 then 1 END) as Available, 
count(case when TS.Status=0 then 1 END) as NotAvailable
from TblMaster TM 
INNER JOIN TblStatus TS ON (TM.ServiceId = TS.ServiceId)
where TM.StartTime <= Time(TS.Updated_Date) and TM.EndTime >= Time(TS.Updated_Date)
group by Date(TS.Updated_Date),ServiceId;