SQL - перенести значение производного столбца, пока заполнен другой столбец - PullRequest
0 голосов
/ 10 апреля 2019

Я использую Teradata 16.20.Предположим, у меня есть следующие данные в таблице.

Это небольшое подмножество, в нем более десятка столбцов и тысячи пользователей с несколькими строками, каждый раз, когда значение изменяется в столбце для пользователя, новая строка вставляется с определенным as_of_dt.Это журнал транзакций для изменений для пользователя.

╔══════╦════════════╦══════════════╦═══════════╗
║ User ║  As_Of_DT  ║ Job_Location ║ temp_asgn ║
╠══════╬════════════╬══════════════╬═══════════╣
║ ABC  ║ 2018.01.01 ║ MT           ║           ║
║ ABC  ║ 2018.01.15 ║ MT           ║           ║
║ ABC  ║ 2018.02.01 ║ SD           ║ Y         ║
║ ABC  ║ 2018.03.01 ║ SD           ║ Y         ║
║ ABC  ║ 2018.03.15 ║ MT           ║           ║
║ ABC  ║ 2018.05.01 ║ TX           ║ Y         ║
║ ABC  ║ 2018.06.01 ║ TX           ║ Y         ║
║ ABC  ║ 2018.07.01 ║ TX           ║ Y         ║
║ ABC  ║ 2018.09.01 ║ MT           ║           ║
║ ABC  ║ 2019.01.01 ║ AZ           ║           ║
║ ABC  ║ 2019.02.01 ║ TX           ║ Y         ║
║ ABC  ║ 2019.03.01 ║ AZ           ║           ║
╚══════╩════════════╩══════════════╩═══════════╝

Необходим новый столбец с именем Home_Job_Location, который заполняется следующим образом:

Если поле temp_asgn не заполнено, тогда установите Home_Job_Location на Job_Location.

В противном случае используйтеЗначение Job_Location из строки до заполнения temp_asgn и переносите его в Home_Job_Location до тех пор, пока значение temp_asgn больше не будет заполнено.Как это:

╔══════╦════════════╦══════════════╦═══════════════════╦═══════════╗
║ User ║  As_Of_DT  ║ Job_Location ║ Base_Job_Location ║ temp_asgn ║
╠══════╬════════════╬══════════════╬═══════════════════╬═══════════╣
║ ABC  ║ 2018.01.01 ║ MT           ║ MT                ║           ║
║ ABC  ║ 2018.01.15 ║ MT           ║ MT                ║           ║
║ ABC  ║ 2018.02.01 ║ SD           ║ MT                ║ Y         ║
║ ABC  ║ 2018.03.01 ║ SD           ║ MT                ║ Y         ║
║ ABC  ║ 2018.03.15 ║ MT           ║ MT                ║           ║
║ ABC  ║ 2018.05.01 ║ TX           ║ MT                ║ Y         ║
║ ABC  ║ 2018.06.01 ║ TX           ║ MT                ║ Y         ║
║ ABC  ║ 2018.07.01 ║ TX           ║ MT                ║ Y         ║
║ ABC  ║ 2018.09.01 ║ MT           ║ MT                ║           ║
║ ABC  ║ 2019.01.01 ║ AZ           ║ AZ                ║           ║
║ ABC  ║ 2019.02.01 ║ TX           ║ AZ                ║ Y         ║
║ ABC  ║ 2019.03.01 ║ AZ           ║ AZ                ║           ║
╚══════╩════════════╩══════════════╩═══════════════════╩═══════════╝

Я пробовал 2 вещи, упорядочивая по as_of_date

Я пробовал LAG(job_location) over (partition by person_id order by as_of_date), это работает, если есть только 1 строка в хронологическом порядке с temp_asgn, но можетбыть любым количеством строк «temp_asgn» для значения, которое будет передано.

Я также пробовал first_value / last_value, но раздел не работает.Включение столбца temp_asgn в раздел означает, что вместо одного есть два раздела, а если не включить temp_asgn, я получаю первое / последнее значение в хронологическом порядке.

Было бы полезно общее решение, в этой таблице есть несколько таких столбцов, для которых я должен сделать это, основываясь на том, заполнен ли temp_asgn.

1 Ответ

1 голос
/ 10 апреля 2019

Измените временное местоположение на NULL и примените LAST_VALUE плюс параметр IGNORE NULLS:

Last_Value(CASE WHEN temp_asgn IS NULL THEN job_location END IGNORE NULLS)
Over (PARTITION BY person_id
      ORDER BY as_of_date)
...