Рассчитать и создать продолжительность времени из DATETIME, используя записи DISTINCT - PullRequest
0 голосов
/ 07 января 2020

У меня очень большой временной набор данных, показывающий перебои в подаче электроэнергии для всего США в течение двухлетнего периода. Я хочу рассчитать продолжительность простоя, используя отдельные записи из 4 столбцов. Значение «0» для CustomersOut рассматривается как сброс.

Пример:

Utility1, State1, County1, City1, 1500, 0, 2017-12-28 12:25:00
Utility1, State1, County1, City1, 1500, 50, 2018-01-01 03:25:00
Utility1, State1, County1, City1, 1500, 65, 2018-01-01 03:36:00
Utility1, State1, County1, City1, 1500, 40, 2018-01-01 03:55:00
Utility1, State1, County1, City1, 1500, 0, 2018-01-01 04:34:00 

Это означает, что в City1 было 50 покупателей на 11 минут, 65 на 19 минут и 40 из 39 в течение, в общей сложности 55,75 клиентских часов.

Желаемый результат:

Utility1, State1, County1, City1, 1500, 0, 2017-12-28 12:25:00, NULL
Utility1, State1, County1, City1, 1500, 50, 2018-01-01 03:25:00, 00:11.00
Utility1, State1, County1, City1, 1500, 65, 2018-01-01 03:36:00, 00:19.00
Utility1, State1, County1, City1, 1500, 40, 2018-01-01 03:55:00, 00:39.00
Utility1, State1, County1, City1, 1500, 0, 2018-01-01 04:34:00, NULL

Table Image

1 Ответ

1 голос
/ 07 января 2020

Вы можете начать с подзапроса, который вычисляет разницу между текущей записью и следующей. Затем внешний запрос фильтрует записи, соответствующие отключениям и агрегатам электропитания:

select 
     UtilityName, 
     StateName, 
     CountyName, 
     CityName,
     sum(CustomersOut) CustomersOut,
     sum(MinutesOut) MinutesOut,
     sum(CustomersOut * MinutesOut) / 60.0 CustomersHoursOut
from (
    select 
        UtilityName, 
        StateName, 
        CountyName,
        CityName,
        CustomersOut,
        datediff(
            minute,
            RecordedDateTime,
            lead(RecordedDateTime) over(
                partition by UtilityName, StateName, CountyName, CityName 
                order by RecordedDateTime
            )
        ) MinutesOut
    from mytable 
) t
where CustomersOut > 0
group by
     UtilityName, 
     StateName, 
     CountyName, 
     CityName

Демонстрация на БД Fiddle :

UtilityName | StateName | CountyName | CityName | CustomersOut | MinutesOut | CustomersHoursOut
:---------- | :-------- | :--------- | :------- | -----------: | ---------: | :------------------
Utility1    | State1    | County1    | City1    |          155 |         69 | 55.750000          

РЕДАКТИРОВАТЬ

Необходимая информация может быть сгенерирована из внутреннего запроса:

select 
    t.*,
    case when CustomersOut > 0
    then datediff(
        minute,
        RecordedDateTime,
        lead(RecordedDateTime) over(
            partition by UtilityName, StateName, CountyName, CityName 
            order by RecordedDateTime
        )
    ) 
    end MinutesOut
from mytable t

Демо :

UtilityName | StateName | CountyName | CityName | CustomersTracked | CustomersOut | RecordedDateTime    | MinutesOut
:---------- | :-------- | :--------- | :------- | ---------------: | -----------: | :------------------ | ---------:
Utility1    | State1    | County1    | City1    |             1500 |            0 | 2017-12-28 12:25:00 |       <em>null</em>
Utility1    | State1    | County1    | City1    |             1500 |           50 | 2018-01-01 03:25:00 |         11
Utility1    | State1    | County1    | City1    |             1500 |           65 | 2018-01-01 03:36:00 |         19
Utility1    | State1    | County1    | City1    |             1500 |           40 | 2018-01-01 03:55:00 |         39
Utility1    | State1    | County1    | City1    |             1500 |            0 | 2018-01-01 04:34:00 |       <em>null</em>
...