Преобразование таблицы по дате в новую таблицу «из-в» - PullRequest
0 голосов
/ 24 февраля 2020

У нас есть система инфраструктуры на рельсах. Все компоненты имеют дату Valid_From и Valid_To. Для данного проекта нам нужно объединить до 8 таблиц, и каждый из слоев может иметь разные периоды. Таким образом, единственный быстрый способ найти правильную комбинацию каждого слоя - это выполнить это с таблицей дат. Работает нормально и правильно. Но теперь у меня есть в качестве примера такая таблица.

CREATE TABLE [ods_tr_amelie].[INES_DATA_PREP_INES_ROUTING_OK]
(
    [MAP_DATE] [DATE] NULL,
    [FROM_ID_PK] [BIGINT] NOT NULL,
    [FROM_INES_KPO] [INT] NULL,
    [TO_ID_PK] [BIGINT] NOT NULL,
    [ROUT_MAX_SPEED] [INT] NULL
)
WITH
(
    DISTRIBUTION = HASH ( [MAP_DATE] ),
    CLUSTERED COLUMNSTORE INDEX
)

Теперь я хотел бы преобразовать это обратно в таблицу VALID_FROM - VALID_TO. Но ... Так как это работает на Azure SQL Datawarehouse, я не могу использовать курсоры, должен выполняться в обычном режиме. Выбирает со ссылками на себя в необходимом.

Ключ на какой период должны быть созданы значения FROM_ID_PK, FROM_INES_KPO, TO_ID_PK и ROUT_MAX_SPEED.

A MIN (MAP_DATE) и MAX (MAP_DATE) неверны, как показано в упрощенном образце данных ниже.

MAP_DATE   SYMBOLIC_KEY
01/01/2020 VALUE_X
01/02/2020 VALUE_Y
01/03/2020 VALUE_X
01/04/2020 VALUE_X

MIN_MAX Создаст

SYMBOLIC_KEY VALID_FROM VALID_TO
VALUE_X      01/01/2020 01/04/2020
VALUE_Y      01/02/2020 01/02/2020

И желаемый результат будет

SYMBOLIC_KEY VALID_FROM VALID_TO
VALUE_X      01/01/2020 01/01/2020
VALUE_Y      01/02/2020 01/02/2020
VALUE_X      01/03/2020 01/04/2020

Любое предложение было бы замечательно ..

1 Ответ

1 голос
/ 24 февраля 2020

Это проблема разрыва и островов. Вы можете использовать row_number() и агрегацию:

select symbolic_value, min(map_date), max(map_date)
from (select t.*,
             row_number() over (order by map_date) as seqnum,
             row_number() over (partition by symbolic_value order by map_date) as seqnum_1
      from INES_DATA_PREP_INES_ROUTING_OK t
     ) t
group by symbolic_value, (seqnum - seqnum_1);

Примечание. В данных отсутствуют пробелы в датах. Эта версия игнорирует пробелы. Если вы хотите, чтобы они создали отдельные группы, то:

select symbolic_value, min(map_date), max(map_date)
from (select t.*,
             row_number() over (order by map_date) as seqnum
      from INES_DATA_PREP_INES_ROUTING_OK t
     ) t
group by symbolic_value, datediff(day, - seqnum, map_date);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...