2017-07-31 49 views
0

我想加入3個表,我沒有IF ELSE下面的SQL。如何將Oracle SQL IF ELSE插入到UPDATE語句中?

update transaction t 
set t.lid= (
select l.id from list l 
inner join distance d 
on l.ueid=d.ueid 
inner join transaction t2 
on t2.id=d.id 
) 

唯一的問題是語句

select l.id from list l 
    inner join distance d 
    on l.ueid=d.ueid 
    inner join transaction t2 
    on t2.id=d.id 

返回一個值中更多,我不能把它分配給t.gid。根據我們的業務規則,如果返回多個值,我必須將t.gid設置爲空。如果內部select語句返回多個值,如何在此sql中包含else語句以返回null?我在網上看過其他帖子,但主要是程序或功能。

編輯:

的基本思路是,以更新所有行上交易表,如果l.id上市表只返回一個值(即在內部連接與距離表)。如果返回多個值,我必須將其更新爲空。所以我不完全確定我是否應該只使用t或t2

+0

你正在更新的't'和子查詢之間似乎沒有任何相關性 - 是't2'所需要的,如果不是這樣的話,那麼這是一次性更新或者你真的應該用視圖?還有一些樣本數據和預期結果可能會有用。而'uid'是一個保留字,那麼這真的是一個帶引號的標識符嗎? –

+0

@AlexPoole我更新了我的問題(請參閱編輯)。 uid是一個錯字。這是ueid。 – WowBow

回答

2

您可以使用a case expression檢查值的合計數爲每個ID:

select t2.id, case when count(l.id) > 1 then null else max(l.id) end as lid 
from list l 
inner join distance d on l.ueid=d.ueid 
inner join transaction t2 on t2.id=d.id 
group by t2.id 

然後使用它作爲一個子查詢,與相關 - 例如 - 來自transaction表的ID:

update transaction t 
set t.lid= (
    select case when count(l.id) > 1 then null else max(l.id) end as lid 
    from list l 
    inner join distance d on l.ueid=d.ueid 
    inner join transaction t2 on t2.id=d.id 
    where t2.id = t.id 
    group by t2.id 
) 

其中與where t2.id = t.id子句進行關聯。但如果這是你做檢查,你可能真的不希望t2可言:

update transaction t 
set t.lid= (
    select case when count(l.id) > 1 then null else max(l.id) end as lid 
    from list l 
    inner join distance d on l.ueid=d.ueid 
    where d.id = t.id 
    group by d.id 
) 

where d.id = t.id現在相關。

如果你可能會得到同樣的value, and in that case still want to use that single repeated value instead of null, then you can add a distinct`以計數的多個實例:

update transaction t 
set t.lid= (
    select case when count(distinct l.id) > 1 then null else max(l.id) end as lid 
    from list l 
    inner join distance d on l.ueid=d.ueid 
    where d.id = t.id 
    group by d.id 
) 

未經檢驗的,因爲沒有樣本數據,從工作,並沒有預期的結果,但希望對齊與你的描述......

另外請注意,這將更新現有的transaction.lid值爲null如果在子查詢沒有匹配值 - 不只是當有多個匹配。如果這不是你想要發生的,那麼你可以使用exists子句添加一個過濾器來限制哪些行被更新。您也可以使用merge,但update可能在這裏更簡單和更清晰。

+0

這對我來說似乎是一個很好的解決方案。自運行sql以來已經有30分鐘了。我們在交易表上有100萬行。你有沒有辦法測試這可能只適用於1000行?謝謝。 – WowBow

+1

您可以使用mod(ID,100000)= 0的位置來測試更小的一組行。您可以通過mod(id,10000)...輕鬆地增加樣本大小,並通過mod(id,1000000)等減少樣本大小。 – zundarz

+1

@zundarz更簡單的方法是添加「where rownum <11」(或任何你選擇的號碼)。這是限制SQL語句工作的行數的標準Oracle方法。我通常在select語句中使用它,爲了確保我不是「吹煙」,我只是用更新語句對它進行了測試:它工作正常。 –