【问题标题】:Calculate cumulative run years/hour based on vehicle performance根据车辆性能计算累计运行年/小时
【发布时间】:2021-10-18 11:47:17
【问题描述】:

条件一: 如果车辆没有发生故障,则计算车辆开始日期到今天日期之间的累计运行小时数。

条件 2: 如果车辆发生故障,计算车辆启动日期到故障日期之间的累积运行小时数

注意:每辆车都有多个/单个开始日期和多个/单个/无失败日期。所以计算每个车辆 ID 的累计运行小时数/年

下面的示例 SQL 表,

Vehicle_ID status date_on
1 Start 2018-05-23
1 Start 2021-06-15
1 Failed 2020-08-10
2 Start 2019-06-23
3 Start 2010-04-20
3 Failed 2010-05-10
4 Start 2011-01-20
4 Failed 2015-01-14
4 Start 2016-02-25
4 Failed 2019-04-10
5 Start 2015-01-14
5 Start 2018-03-16
6 Start 2019-04-10
6 Failed 2020-02-10
6 Failed 2021-04-11
7 Start 2011-01-14
7 Start 2016-03-16
7 Start 2019-04-10
7 Failed 2020-02-10

上面的车辆 ID 1 有 2 个开始日期和 1 个失败日期,因此计算第一个开始日期到第一个失败日期 + 第二个开始日期到截止日期之间的运行年数(第二个开始日期之后没有发生故障)。

车辆 ID 4 有 2 个开始日期 2 个失败日期,因此计算第一个开始日期到第一个失败日期 + 第二个开始日期到第二个失败日期之间的运行年数。

我尝试了以下代码来计算从开始日期到失败日期之间的运行时间,但在排除以下情况下的车辆 ID 时遇到了困难。

我得到如下格式的结果

VehicleID Run_years
1 2.358
4 7.109

以上运行年数根据以下计算,

车辆 ID 1:

第一个开始到第一个失败 = 2.21917

第二次开始到截止日期(车辆 ID 1 中没有第二次失败)= 0.13972

所以总运行年数 = 2.3589。

车辆 ID 4:

第一个开始到第一个失败 = 3.986

第二个开始到第二个失败日期 = 3.123

所以总和运行年 = 7.109。

** 排除场景所需的声明**

车辆 ID 5

车辆 ID 5 有 2 个开始日期。在第一个开始日期之后缺少失败的日期。所以在计算运行年数时排除它。

车辆 ID 6

车辆 ID 6 有 2 个失败日期和 1 个开始日期。在第一个失败日期之后缺少第二个开始日期。所以在计算运行年数时排除它。

车辆 ID 7

车辆 ID 7 有 3 个开始日期和 1 个失败日期。在第二个开始日期之后缺少第二个失败的日期。所以在计算运行年数时排除它。

我需要的实际逻辑开始日期的计数 - 失败日期的计数是 2 或 -1 或 -2 然后排除运行年计算。

以下代码用于在不排除上述条件的情况下计算运行时间

select
  s.vehicle_id,
  sum(datediff(day, date_on, isnull(m.min_dt, getdate()))/365.0) run_years
from #samples s
cross apply (
        select min(date_on) min_dt
               from #samples ss
               where s.vehicle_id = ss.vehicle_id
                        and s.date_on < ss.date_on
                        and ss.stat = 'Failed'
) m
where s.stat = 'Start'
group by s.vehicle_id
order by s.vehicle_id;

【问题讨论】:

    标签: sql sql-server database tsql


    【解决方案1】:

    您可以通过反向计数失败来为每组“开始”和“失败”分配一个组。然后汇总每个“期间”:

    select vehicle_id,
           min(case when status = 'start' then date_on end) as start_date,
           coalesce(max(case when status = 'fail' then date_on end),
                    getdate()
                   ) as end_date,
           datediff(hours,
                    min(case when status = 'start' then date_on end) as start_date,
                    coalesce(max(case when status = 'fail' then date_on end),
                             getdate()
                   ) as diff_hours             
    from (select t.*,
                 sum(case when status = 'fail' then 1 else 0 end) over (partition by vehicle_id order by date_on) as grp
    
          from t
         ) t
    group by vehicle_id, grp;
    

    如果您想要每个 vehicle 的总数,您可以再次聚合。

    此外,这提供了小时的差异。

    【讨论】:

    • @Rock 这能回答你的问题吗?
    猜你喜欢
    • 2021-11-05
    • 2019-05-05
    • 2017-07-16
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 2022-06-17
    • 1970-01-01
    相关资源
    最近更新 更多