Teradata SQL 获取最后一个非空值
Teradata SQL getting last not null value
我在 Teradata 中有一个 table,如下所示:
Account_Num Install_Due_Dt Install_Num Install_Pay_Dt
12805196 12/08/2019 1 12/08/2019
12805196 10/09/2019 2 ?
12805196 10/10/2019 3 ?
12805196 11/11/2019 4 13/09/2019
12805196 10/12/2019 5 ?
我需要用第一个非空值填充 Install_Pay_Dt 列。例如,它应该是这样的:
Account_Num Install_Due_Dt Install_Num Install_Pay_Dt
12805196 12/08/2019 1 12/08/2019
12805196 10/09/2019 2 12/08/2019
12805196 10/10/2019 3 12/08/2019
12805196 11/11/2019 4 13/09/2019
12805196 10/12/2019 5 13/09/2019
我使用的是 Teradata 15,所以无法使用延迟。我一直在搜索,但找不到解决方案。 ID 列是 Account_Num,order 列是 Install_num.
我试过这样做:
coalesce(Install_Pay_Dt, MAX(lag_)
OVER(PARTITION BY 1 ORDER BY Install_Num asc
ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)) as lag
但它只填满了第二行。
我确定有一种更简洁的方法可以做到这一点,但这里有一个选择:
SELECT
acct.Account_Num,
acct.Install_Due_Dt,
acct.Install_Num,
COALESCE(
acct.Install_Pay_Dt, -- Use original value, if not null
dt.Install_Pay_Dt_Default -- Use default value if original is null
) AS Install_Pay_Dt
FROM MyTable acct
LEFT JOIN (
SELECT Install_Pay_Dt AS Install_Pay_Dt_Default
FROM MyTable
WHERE Install_Pay_Dt IS NOT NULL -- Only get non-NULL values
QUALIFY ROW_NUMBER() OVER(ORDER BY Install_Num) = 1 -- Only get first row
) dt ON 1=1 -- LEFT JOIN instead of CROSS JOIN in case there are no "install_pay_dt" values
这假设您希望将 "default value" 逻辑作为一个组应用于所有行,这是您发布的查询向我建议的,因为 PARTITION BY 1
将处理单个分区中的所有行。如果您想按 account_num
行组应用逻辑,则必须稍微修改一下。
last_value
与lag
非常相似,都支持IGNORE NULLS
选项
last_value(Install_Pay_Dt IGNORE NULLS)
over (partition by Account_Num
order by Install_Num )
我在 Teradata 中有一个 table,如下所示:
Account_Num Install_Due_Dt Install_Num Install_Pay_Dt
12805196 12/08/2019 1 12/08/2019
12805196 10/09/2019 2 ?
12805196 10/10/2019 3 ?
12805196 11/11/2019 4 13/09/2019
12805196 10/12/2019 5 ?
我需要用第一个非空值填充 Install_Pay_Dt 列。例如,它应该是这样的:
Account_Num Install_Due_Dt Install_Num Install_Pay_Dt
12805196 12/08/2019 1 12/08/2019
12805196 10/09/2019 2 12/08/2019
12805196 10/10/2019 3 12/08/2019
12805196 11/11/2019 4 13/09/2019
12805196 10/12/2019 5 13/09/2019
我使用的是 Teradata 15,所以无法使用延迟。我一直在搜索,但找不到解决方案。 ID 列是 Account_Num,order 列是 Install_num.
我试过这样做:
coalesce(Install_Pay_Dt, MAX(lag_)
OVER(PARTITION BY 1 ORDER BY Install_Num asc
ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)) as lag
但它只填满了第二行。
我确定有一种更简洁的方法可以做到这一点,但这里有一个选择:
SELECT
acct.Account_Num,
acct.Install_Due_Dt,
acct.Install_Num,
COALESCE(
acct.Install_Pay_Dt, -- Use original value, if not null
dt.Install_Pay_Dt_Default -- Use default value if original is null
) AS Install_Pay_Dt
FROM MyTable acct
LEFT JOIN (
SELECT Install_Pay_Dt AS Install_Pay_Dt_Default
FROM MyTable
WHERE Install_Pay_Dt IS NOT NULL -- Only get non-NULL values
QUALIFY ROW_NUMBER() OVER(ORDER BY Install_Num) = 1 -- Only get first row
) dt ON 1=1 -- LEFT JOIN instead of CROSS JOIN in case there are no "install_pay_dt" values
这假设您希望将 "default value" 逻辑作为一个组应用于所有行,这是您发布的查询向我建议的,因为 PARTITION BY 1
将处理单个分区中的所有行。如果您想按 account_num
行组应用逻辑,则必须稍微修改一下。
last_value
与lag
非常相似,都支持IGNORE NULLS
选项
last_value(Install_Pay_Dt IGNORE NULLS)
over (partition by Account_Num
order by Install_Num )