Как правильно агрегировать эти строки? - PullRequest
2 голосов
/ 21 мая 2019

У меня есть таблица и строки, как показано ниже минимального образца. Я хочу более разумный способ получить ожидаемые результаты. У кого-нибудь есть хорошая идея?

create table foo (
    id int,
    s datetime,
    e datetime,
    value float
);

insert foo values
    (1, '2019-1-1 1:00:00', '2019-1-1 3:00:00', 10.0),
    (1, '2019-1-1 1:30:00', '2019-1-1 3:00:00', 10.0),
    (1, '2019-1-1 4:00:00', '2019-1-1 5:00:00', 10.0),
    (1, '2019-1-1 4:30:00', '2019-1-1 6:00:00', 10.0),  
    (2, '2019-1-1 2:00:00', '2019-1-1 6:00:00', 15.0),  
    (2, '2019-1-1 2:00:00', '2019-1-1 6:00:00', 10.0);

Я хочу получить такие результаты.

1, '2019-1-1 1:00:00', '2019-1-1 3:00:00', 10.0
1, '2019-1-1 4:00:00', '2019-1-1 6:00:00', 10.0 
2, '2019-1-1 2:00:00', '2019-1-1 6:00:00', 15.0

У них более длинный период, объединенные s и e, которые будут более длинным периодом, и большее значение, чем у строк с перекрывающимися периодами.

Дополнительная информация

Я думал, что «умный путь» легче понять (например, чем меньше подзапросов, тем лучше) и быстрее выполнять.

На самом деле, у меня есть дополнительный столбец географии Point для таблицы «foo» в примере кода, и мне нужно выбрать точку из строки с самым низким «значением» в той же группе периодов времени. Я однажды подумал о своей логике. Я понятия не имею, чтобы получить результат без многих подзапросов или курсора. Поэтому я хотел сделать мою проблему более простой, чтобы получить представление об этом деле.

Ответы [ 2 ]

2 голосов
/ 21 мая 2019

Это тип проблемы пробелов и островков.Вы можете решить эту проблему, определив, когда начинаются перекрывающиеся периоды времени, то есть период времени не перекрывается с любыми предшествующими периодами времени.

Затем совокупная сумма пусков определяет группу.И вы можете агрегировать по группе:

select id, min(s) as s, max(e) as e, max(value)
from (select f.*,
             sum(case when max_e < s then 1 else 0 end) over (partition by id order by s) as grp
      from (select f.*,
                   max(e) over (partition by id order by s rows between unbounded preceding and 1 preceding) as max_e
            from foo f
           ) f
     ) f
group by id, grp;

Здесь - это дБ <> скрипка.

0 голосов
/ 21 мая 2019

использовать функцию агрегации max ()

select id,s,e,max(value) from table
group by id,s,e
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...