Рассчитайте совокупный пробег в годах/час на основе характеристик транспортного средства

#sql #sql-server #database #tsql

Вопрос:

Условие 1: если транспортное средство не вышло из строя, рассчитайте суммарные часы пробега между датой запуска транспортного средства и сегодняшней датой.

Условие 2: если транспортное средство вышло из строя, рассчитайте совокупные часы работы между датой запуска транспортного средства и датой выхода из строя

Примечание: каждое транспортное средство имеет несколько/одну дату запуска и несколько/одну/ни одной даты сбоя. поэтому рассчитайте совокупные часы/годы работы для каждого идентификатора транспортного средства

Пример таблицы SQL ниже,

Идентификатор транспортного средства Статус дата на
1 Начать 2018-05-23
1 Начать 2021-06-15
1 Неудачный 2020-08-10
2 Начать 2019-06-23
3 Начать 2010-04-20
3 Неудачный 2010-05-10
4 Начать 2011-01-20
4 Неудачный 2015-01-14
4 Начать 2016-02-25
4 Неудачный 2019-04-10
5 Начать 2015-01-14
5 Начать 2018-03-16
6 Начать 2019-04-10
6 Неудачный 2020-02-10
6 Неудачный 2021-04-11
7 Начать 2011-01-14
7 Начать 2016-03-16
7 Начать 2019-04-10
7 Неудачный 2020-02-10

вышеуказанный идентификатор транспортного средства 1 имеет 2 даты начала и 1 дату сбоя, поэтому рассчитайте годы работы между первой датой запуска и первой датой сбоя второй датой запуска до даты завершения( после второй даты запуска сбоя не произошло).

Идентификатор транспортного средства 4 имеет 2 даты начала 2 даты сбоя, поэтому рассчитайте годы работы между первой датой запуска и первой датой сбоя второй датой запуска и второй датой сбоя.

Я попытался выполнить следующий код для расчета часов работы между датой начала и датой сбоя, но получил борьбу за исключение идентификатора транспортного средства для условий ниже.

Я получаю результат в следующем формате

Идентификатор транспортного средства Run_years
1 2.358
4 7.109

Above Run years calculated based on below,

Vehichle Id 1:

1-й запуск до 1-го неудачного = 2,21917

2-й запуск до даты(нет 2-го сбоя в идентификаторе транспортного средства 1) = 0,13972

таким образом, сумма лет выполнения = 2,3589.

Идентификационный номер транспортного средства 4:

1-й запуск до 1-го неудачного = 3,986

со 2-го начала до 2-й неудачной даты = 3.123

таким образом, сумма лет выполнения = 7,109.

** Требуемое заявление для сценария исключения**

Идентификационный номер транспортного средства 5

идентификатор транспортного средства 5 имеет 2 даты начала. дата сбоя отсутствует после 1-й даты начала. поэтому исключите это для расчета лет выполнения.

Идентификационный номер транспортного средства 6

идентификатор транспортного средства 6 содержит 2 даты сбоя и 1 дату запуска. 2-я дата начала отсутствует после 1-й неудачной даты. поэтому исключите это для расчета лет выполнения.

Идентификационный номер транспортного средства 7

идентификатор транспортного средства 7 содержит 3 даты начала и 1 дату сбоя. 2-я неудачная дата отсутствует после 2-й даты начала. поэтому исключите это для расчета лет выполнения.

Фактическая логика, которую я требовал, количество дат начала — количество неудачных дат равно 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;
 

Ответ №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 .

Кроме того, это обеспечивает разницу в часах.

Комментарии:

1. @Rock это ответ на ваш вопрос?