Сравнить записи и генерировать записи - PullRequest
0 голосов
/ 15 октября 2019

Мое требование - расположить записи в хронологическом порядке и сравнить каждую запись с ее следующей последовательной записью. Если 2-я запись отличается от предыдущей записи (в порядке asc), относящейся к какому-либо полю, и запись является активной (т.е.flag = 'F'), то разделите 2-ю запись, создав запись с eff_date = eff_dt второй записи- 1 день. Если следующая запись неактивна (т. Е. Flag = 'C', то выводится только эта запись, но нет необходимости разбивать ее и создавать новую запись. Продолжите это сравнение для всех записей.

Например,

product | eff_dt | store | region | type
12345 | 18/05/2017 | HA | CA | F
12345 | 05/10/2018 | K1 | CA | F
12345 | 01/02/2019 | K1 | CA | F
12345 | 15/07/2019 | AB | GA | C
12345 | 07/09/2019 | BT | MD | F

Из приведенной выше таблицы сначала мы размещаем записи в хронологическом порядке.
Теперь мы сравниваем первую запись со второй записью и видим, что «store» изменился во второй записи HA -> K1, а вторая записьactive (flag = F). Следовательно, и первая запись, и вторая запись необходимы для вывода, а вторая запись будет разделена на 2 части - новая запись создается с (eff_dt - 1) днём.
Сейчаскогда мы сравниваем третью запись со второй записью, мы видим, что в значениях любого поля нет изменений, а также что запись активна, и, следовательно, эта запись будет игнорироваться и не будет выводиться.
Теперьмы сравниваем четвертую запись с третьей записью, которую мы видим, что она неактивна (flag = 'C'), следовательно, эта запись будет выводиться как есть, но новая запись не будет сгенерирована. что мы сделали для первого сценария.
Наконец, 5-я запись является первой Активной записью после того, как продукт был закрыт (в 4-й записи), следовательно, будеттакже будет выводиться, но новая запись не будет создана.

Ожидаемый результат будет:

product | eff_dt | store | region | type
12345 | 18/05/2017 | HA | CA | F      <<--- output
12345 | 04/10/2017 | HA | CA | F      <<--- new record generated with (eff_dt - 1)
12345 | 05/10/2018 | K1 | CA | F      <<--- output as-is
                                           <<--- record not output since no change in values
12345 | 15/07/2019 | AB | GA | C      <<--- record has changes but also Inactive. Hence, output as-is and new record generation not required
12345 | 07/09/2019 | BT | MD | F      <<--- record output since this indicates product is reopened and is active again. No new record required.

Может ли кто-нибудь помочь с вышеуказанной логикой и как разделить запись, создав новуюзапись с eff_dt - 1. Пожалуйста, дайте мне знать, если необходима дополнительная информация / уточнение

1 Ответ

0 голосов
/ 15 октября 2019

Хммм. Я интерпретирую это как проблему разрыва и островков с некоторыми поворотами. Вместо того, чтобы помещать «конечные» значения в разные строки, я бы поместил эффективные и конечные даты в одну строку:

select product, store, region, type,
       min(eff_dt),
       date_add(lead(eff_dt) over (partition by product order by min(eff_dt), -1) as
from (select t.*,
             row_number() over (partition by product order by eff_dt) as seqnum_p,
             row_number() over (partition by product, store, region, type order by eff_dt) as seqnum_psrt
      from t
     ) t
group by product, store, region, type, (seqnum - seqnum_psrt);

Если вы хотите это в разных строках, вы можете использовать union all:

select product, store, region, type, eff_dt
from (select t.*,
             lag(eff_dt) over (partition by product, store, region, type order by eff_dt) as prev_psrt_date,
             lag(eff_dt) over (partition by product order by eff_dt) as prev_date
      from t
     ) t
where prev_date is null or prev_date <> prev_psrt_date
union all
select product, store, region, type,
       date_add(next_date, 1)
from (select t.*,
             lead(eff_dt) over (partition by product, store, region, type order by eff_dt) as next_psrt_date,
             lead(eff_dt) over (partition by product order by eff_dt) as next_date
      from t
     ) t
where next_date <> next_psrt_date or next_psrt_date is null;

Хитрость при поиске строк с одинаковыми значениями заключается в сравнении предыдущей / следующей даты - но по разным разделам данных. Это проще, чем сравнивать каждый столбец независимо, и это также работает для NULL значений.

...