Oracle 更新使用滞后功能
Oracle Update using Lag function
我正在尝试使用 lag
函数在 SCD2
维度中 update
有效开始日期。我正在尝试使用子查询根据 PK 自行加入 table。更新不会根据之前的结束日期进行更新,而只会更新为默认值(它本身)。当我删除默认值时出现错误,因为有效开始日期不能为空。当我只使用 select
时,我得到了想要的结果。
非常感谢任何帮助,我相信这很简单!
update schema.d_account ac1
set effective_start_dt = (select lag(effective_end_dt, 1, effective_start_dt) over(partition by id order by effective_end_dt asc)
from schema.d_account ac2
where ac1.account_dim_key = ac2.account_dim_key),
audit_last_update_dt = sysdate,
where id in '0013600000USKLqAAP'
Table:
想要的结果:
您的更新无法正常工作可能是以下原因之一。我不知道你的table的确切结构。您尚未提供示例数据。如果您的 account_dim_key 对于每一行都是唯一的,那么 select lag() ... from schema.d_account ac2 where ac1.account_dim_key = ac2.account_dim_key)
将 return 一行,您将有效地将 effective_start_dt
更新为 effective_start_dt
(默认值滞后函数)
如果您作为示例提供的所有这些行的 account_dim_key 都相同,那么 select lag() ... from schema.d_account ac2 where ac1.account_dim_key = ac2.account_dim_key)
将 return 多行并且 Oracle 将抱怨无法更新(有具体报错信息,具体写法不记得了。
要使您的查询正常工作,您需要使用不同的方法:
update schema.d_account ac1
set effective_start_dt = (select prev_dt from
(select lag(effective_end_dt, 1, effective_start_dt) over(partition by id order by effective_end_dt asc) as prev_dt
, ROWID as rid
from schema.d_account ac2) a where a.rid = ROWID),
audit_last_update_dt = sysdate,
where id in '0013600000USKLqAAP'
所以,基本上您有一个子查询 a
,其中包含您构建前一个日期的 ROWID 列。对于 UPDATE 语句,您通过 ROWID 加入此子查询。
注意:如果您的 account_dim_key 对于每一行都是唯一的,您可以使用它代替 ROWID:您可能会获得更好的性能,具体取决于您为 table[=17 设置的索引=]
更新:上述查询可能会给您带来糟糕的表现。使用下面的 MERGE 语句会更好:
MERGE INTO (SELECT id, effective_start_dt, ROWID rid, audit_last_update_dt
FROM schema.d_account WHERE id in '0013600000USKLqAAP') ac1
USING (select lag(effective_end_dt, 1, effective_start_dt) over(partition by id order by effective_end_dt asc) as prev_dt
, ROWID as rid
from schema.d_account) ac2
ON (ac1.rid = ac2.rid)
WHEN MATCHED THEN UPDATE SET ac1.effective_start_dt = ac2.prev_dt,
ac1.audit_last_update_dt = sysdate;
我正在尝试使用 lag
函数在 SCD2
维度中 update
有效开始日期。我正在尝试使用子查询根据 PK 自行加入 table。更新不会根据之前的结束日期进行更新,而只会更新为默认值(它本身)。当我删除默认值时出现错误,因为有效开始日期不能为空。当我只使用 select
时,我得到了想要的结果。
非常感谢任何帮助,我相信这很简单!
update schema.d_account ac1
set effective_start_dt = (select lag(effective_end_dt, 1, effective_start_dt) over(partition by id order by effective_end_dt asc)
from schema.d_account ac2
where ac1.account_dim_key = ac2.account_dim_key),
audit_last_update_dt = sysdate,
where id in '0013600000USKLqAAP'
Table:
想要的结果:
您的更新无法正常工作可能是以下原因之一。我不知道你的table的确切结构。您尚未提供示例数据。如果您的 account_dim_key 对于每一行都是唯一的,那么 select lag() ... from schema.d_account ac2 where ac1.account_dim_key = ac2.account_dim_key)
将 return 一行,您将有效地将 effective_start_dt
更新为 effective_start_dt
(默认值滞后函数)
如果您作为示例提供的所有这些行的 account_dim_key 都相同,那么 select lag() ... from schema.d_account ac2 where ac1.account_dim_key = ac2.account_dim_key)
将 return 多行并且 Oracle 将抱怨无法更新(有具体报错信息,具体写法不记得了。
要使您的查询正常工作,您需要使用不同的方法:
update schema.d_account ac1
set effective_start_dt = (select prev_dt from
(select lag(effective_end_dt, 1, effective_start_dt) over(partition by id order by effective_end_dt asc) as prev_dt
, ROWID as rid
from schema.d_account ac2) a where a.rid = ROWID),
audit_last_update_dt = sysdate,
where id in '0013600000USKLqAAP'
所以,基本上您有一个子查询 a
,其中包含您构建前一个日期的 ROWID 列。对于 UPDATE 语句,您通过 ROWID 加入此子查询。
注意:如果您的 account_dim_key 对于每一行都是唯一的,您可以使用它代替 ROWID:您可能会获得更好的性能,具体取决于您为 table[=17 设置的索引=]
更新:上述查询可能会给您带来糟糕的表现。使用下面的 MERGE 语句会更好:
MERGE INTO (SELECT id, effective_start_dt, ROWID rid, audit_last_update_dt
FROM schema.d_account WHERE id in '0013600000USKLqAAP') ac1
USING (select lag(effective_end_dt, 1, effective_start_dt) over(partition by id order by effective_end_dt asc) as prev_dt
, ROWID as rid
from schema.d_account) ac2
ON (ac1.rid = ac2.rid)
WHEN MATCHED THEN UPDATE SET ac1.effective_start_dt = ac2.prev_dt,
ac1.audit_last_update_dt = sysdate;