簡體   English   中英

使用滯后功能的Oracle Update

[英]Oracle Update using Lag function

我正在嘗試使用lag函數來update SCD2維度中的有效開始日期。 我正在嘗試使用子查詢自行基於PK聯接表。 該更新將不會基於上一個結束日期進行更新,而只會更新為默認值(其本身)。 當我刪除默認值時,由於有效的開始日期不能為空,所以會出現錯誤。 當我只使用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'

表:

在此處輸入圖片說明

所需結果:

在此處輸入圖片說明

您的更新無法正常工作的原因可能有以下之一。 我不知道您的桌子的確切結構。 您尚未提供樣本數據。 如果您的account_dim_key對於每一行都是唯一的, select lag() ... from schema.d_account ac2 where ac1.account_dim_key = ac2.account_dim_key)將返回一行,並且您將有效effective_start_dt將有效select lag() ... from schema.d_account ac2 where ac1.account_dim_key = ac2.account_dim_key)更新為effective_start_dt select lag() ... from schema.d_account ac2 where ac1.account_dim_key = ac2.account_dim_key) (為默認值滯后函數)

如果您作為示例提供的所有這些行的account_dim_key都相同, select lag() ... from schema.d_account ac2 where ac1.account_dim_key = ac2.account_dim_key)將返回多行,並且Oracle將抱怨UPDATE是不可能的(有特定的錯誤消息,我不記得確切的措辭了。

為了使查詢正常工作,您需要使用其他方法:

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:根據表的索引,您可能會獲得更好的性能

更新:上面的查詢可能會給您帶來不好的性能。 使用下面的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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM