Как преобразовать диапазон записей в значения записи после этого диапазона в SQL? - PullRequest
1 голос
/ 04 августа 2020

Я пытаюсь заменить некоторые неправильные входные записи в указанном диапазоне дат c правильными записями. Однако я не уверен, есть ли эффективный способ сделать это. Поэтому мой вопрос: как преобразовать диапазон записей (stati c) в значения записи после этого диапазона в SQL? Ниже вы найдете пример, поясняющий, чего я пытаюсь достичь.

введите описание изображения здесь

В этом примере вы можете видеть, что клиент номер 1 принадлежит к группе номер 0 (Нет) в период с 25.06.2020 по 29.06.2020. С 30.06.2020 по 05.07.2020 этот номер группы изменяется с 0 на 11 для клиента номер 1. Этот период статистики c содержит неверные записи и должен быть изменен на значения, действительные на 06-07. -2020 (номер группы == 10). Есть ли способ сделать это?

Ответы [ 3 ]

1 голос
/ 04 августа 2020

Если я правильно понимаю, вы можете использовать оконные функции для получения данных по этой конкретной дате и case logi c, чтобы назначить их указанному c диапазону дат:

select t.*,
       (case when date >= '2020-07-01' and date <= '2020-07-05'
             then max(case when date = '2020-07-06' then group_number end) over (partition by customer_number)
             else group_number
        end) as imputed_group_number,
       (case when date >= '2020-07-01' and date <= '2020-07-05'
             then max(case when date = '2020-07-06' then role end) over (partition by customer_number)
             else role
        end) as imputed_role
from t;

Если вы хотите обновить значения, вы можете использовать JOIN:

update t
    set group_number = tt.group_number,
        role = tt.role
    from tt
    where tt.customer_number = t.customer_number and tt.date = '2020-07-06'
1 голос
/ 04 августа 2020

В качестве примера вы можете сделать следующее. Здесь я выбрал критерии, согласно которым если role = 'Leader' это плохая запись, и поэтому вы должны применить следующий доступный group_number -> в столбце group_number1 и role1.

Я использовал меньшее подмножество строки, которые у вас есть в вашем примере Excel.

  select date1
        ,customer_number
        ,group_number
        ,case when role='Leader' then 
                  (select t1.group_number
                     from t t1
                    where t1.date1>t.date1
                      and t1.role<>'Leader'
                   order by t1.date1 asc
                   limit 1
                  ) 
             else group_number 
         end as group_number1
        ,role
       ,case when role='Leader' then 
                  (select t1.role
                     from t t1
                    where t1.date1>t.date1
                      and t1.role<>'Leader'
                   order by t1.date1 asc
                   limit 1
                  ) 
             else role 
         end as role1
   from t
order by 1   

+------------+-----------------+--------------+---------------+--------+--------+
|   DATE1    | CUSTOMER_NUMBER | GROUP_NUMBER | GROUP_NUMBER1 |  ROLE  | ROLE1  |
+------------+-----------------+--------------+---------------+--------+--------+
| 2020-06-25 |               1 |            0 |             0 | None   | None   |
| 2020-06-26 |               1 |            0 |             0 | None   | None   |
| 2020-06-27 |               1 |            0 |             0 | None   | None   |
| 2020-06-28 |               1 |            0 |             0 | None   | None   |
| 2020-06-29 |               1 |            0 |             0 | None   | None   |
| 2020-06-30 |               1 |           11 |            10 | Leader | Member |
| 2020-07-01 |               1 |           11 |            10 | Leader | Member |
| 2020-07-06 |               1 |           10 |            10 | Member | Member |
+------------+-----------------+--------------+---------------+--------+--------+

ссылка на скрипт db https://dbfiddle.uk/?rdbms=db2_11.1&fiddle=c95d12ced067c1df94947848b5a94c14

1 голос
/ 04 августа 2020

Я думаю, что оконная функция first_value() делает то, что вы хотите:

select 
    date,
    customer_number,
    first_value(group_number) over(partition by customer_number order by date) group_number,
    first_value(role)         over(partition by customer_number order by date) role
from mytable
...