2017-07-28 86 views
1

選擇在Oracle中,我想這樣做的更新在表上基於在列表中選擇最後一次出現,是這樣的:SQL - 更新最後一次出現在第

UPDATE table t1 
set t1.fieldA = 0 
where t1.id in ( 
    select t2.id, max(t2.TIMESTAMP) 
    from table t2 
    where t2.id in (1111,2222,33333) 
    group by t2.id 
    ); 

此查詢不工作,我收到錯誤「太多值」。 任何想法? 感謝

+0

請不要使用sql-server標記來解答有關oracle的問題。突出顯示代碼(您的sql)並按下文本編輯器上方的括號按鈕{}將您的sql格式化爲快遞字體 –

回答

-1

我相信Oracle支持多列,所以你可以嘗試:

UPDATE table t1 
set t1.fieldA = 0 
where 
    (t1.id,t1.timestamp) in (select t2.id, max(t2.TIMESTAMP) from table t2 where t2.id in (1111,2222,33333) group by t2.id); 

從本質上講,如果你提供了一個子查詢到有兩列的結果集的IN的右側,那麼你必須提供IN左側括號中的兩列名稱順便提一下,如果需求是隻有一行被更新,我從不喜歡根據最大值進行更新,因爲兩個具有相同最大值的行將被更新。這種查詢的好:

Update table 
Set fieldA=0 
Where rowid in(
    select rowid from (
    select rowid, row_number() over(partition by id order by timestamp desc 
) as rown from table 
) where rown=1) 

但是,如果你對錶的主鍵包括時間戳作爲化合物的一部分,那麼就沒有在這裏用相同的ID /時間戳兩行的關注..情況很少!

+0

我試過了您的提議,但收到錯誤:SQL錯誤:ORA-00979:不是GROUP BY表達式 – Braninoca

+0

我的sql工作得很好,看看這個sqlfiddle:http://sqlfiddle.com/#!4/4c124/4 - 如果你得到一個錯誤,這是因爲你在你的sql中編寫了一些不正確的東西, ,回到你正在寫的任何真正的查詢。錯誤消息意味着您忘記將內容列放入內部查詢中的分組列表中。張貼出錯的確切sql,我會告訴你它有什麼問題,但是這肯定與他的建議無關,「把IN的右側的所有列放在IN的左側「 –

+0

的確,我犯了一個錯字。更正後,您的提案有效。 感謝您的快速回復 – Braninoca

0

你的子選擇有2個(太多)字段,所以它不能與ID進行比較。 比較時間戳與最大時間戳。

UPDATE table t1 set t1.fieldA = 0 
where t1.TIMESTAMP = (select max(t2.TIMESTAMP) from table t2 where t2.id = t1.id ) 
and id in (1111,2222,33333) 
+0

此查詢不回答問題。它會導致整個表中只有一行(包含最新的時間戳)被更新,而不是每個ID的最新行。 oP查找一次更新多行的查詢 –

+0

@Caius Jard我認爲你弄錯了,它包含了每個ID的最大時間戳,並刪除了具有該時間戳的記錄 – Turo

+0

道歉,我想我也弄錯了。我不能刪除我的downvote,除非答案是編輯..但我會愉快地刪除它,如果你想做一些無關緊要的編輯!對不起 –