SQL - 在填充另一列时结转派生列值
SQL - Carry forward derived column value while another column is populated
我正在使用 Teradata 16.20。
假设我在table中有如下数据。
这是一个小子集,有十几个列和数千个多行用户,每次用户列中的值更改时,都会插入一个新行,其中包含特定的 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。
否则使用 行 temp_asgn 填充前的 Job_Location 值,并在 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 ║ ║
╚══════╩════════════╩══════════════╩═══════════════════╩═══════════╝
我已经尝试通过 as_of_date
订购了 2 件东西
我试过了
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 只是按时间顺序让我得到 first/last 值。
通用解决方案会有所帮助,此 table 中有几个这样的列,我必须根据是否填充 temp_asgn 来执行此操作。
将临时位置更改为 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)
我正在使用 Teradata 16.20。 假设我在table中有如下数据。
这是一个小子集,有十几个列和数千个多行用户,每次用户列中的值更改时,都会插入一个新行,其中包含特定的 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。
否则使用 行 temp_asgn 填充前的 Job_Location 值,并在 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 ║ ║
╚══════╩════════════╩══════════════╩═══════════════════╩═══════════╝
我已经尝试通过 as_of_date
订购了 2 件东西我试过了
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 只是按时间顺序让我得到 first/last 值。
通用解决方案会有所帮助,此 table 中有几个这样的列,我必须根据是否填充 temp_asgn 来执行此操作。
将临时位置更改为 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)