【问题标题】:SQL - Carry forward derived column value while another column is populatedSQL - 在填充另一列时结转派生列值
【发布时间】:2019-08-31 10:43:24
【问题描述】:

我使用的是 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。

否则,使用 在填充 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),如果 temp_asgn 按时间顺序只有 1 行,则此方法有效,但可以有任意数量的“temp_asgn”行来传递值。

我也试过 first_value/last_value 但分区不起作用。在分区中包含 temp_asgn 列意味着有两个分区而不是一个,并且不包含 temp_asgn 只会按时间顺序获得第一个/最后一个值。

一个通用的解决方案会很有帮助,我必须根据 temp_asgn 是否填充此表中的几个列来执行此操作。

【问题讨论】:

    标签: sql teradata


    【解决方案1】:

    将临时位置更改为 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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-16
      • 2014-01-24
      • 1970-01-01
      • 2022-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多