[英]Is it possible to break sql processing after first matched condition?
假設我有一個表,記錄如下
EmpTable::
Col1 Col2 Col3
1 John Frank
2 Tom Hank
3 Cathy Hoogen
4 Dorothy Fran
我需要根據各種條件查找記錄。 僅當先前條件無法提供結果時,這些條件才需要進入下一個條件。
例如,如果我這樣做
select * from EmpTable where Col3='Frank' OR Col3='Fran';
這將使我同時獲得第1行和第4行。(如果在where子句中應用大小寫,則結果相同)。 我希望sql要做的是在第一次匹配時停止,即當滿足Col3 ='Frank'時停止進一步處理,在這種情況下,它將不返回通過匹配Col3 ='Fran'獲得的結果。 僅當第一個子句失敗時,才應匹配Col3 ='Fran'並返回匹配的行。
我要匹配的條件很長,因此想知道是否有可能僅通過一個查詢就可以有效地做到這一點?,
我確實有替代方法,即編寫一個sql程序包,並對第一個子句進行存在檢查,並在存在時中斷並返回結果集,然后使用不同的子句去運行下一個查詢,依此類推。 如果匹配,此程序包可以返回1行或更多行。
非常感謝任何指針。
如果只需要一行,則可以使用:
select *
from EmpTable
where Col3 in ('Frank', 'Fran')
order by (case when col3 = 'Frank' then 1 else 2 end)
fetch first 1 row only;
如果允許多個匹配項(或在舊版本的Oracle中),則可以使用窗口函數:
select e.*
from (select e.*,
rank() over (order by (case when col3 = 'Frank' then 1 else 2 end)) as seqnum
from EmpTable e
where col3 in ('Frank', 'Fran')
) e
where seqnum = 1;
上面的兩個查詢可以輕松地概括為多個名稱。 您還可以將not exists
與union all
用於兩個名稱:
select e.*
from EmpTable e
where e.Col3 = 'Frank'
union all
select e.*
from EmpTable e
where e.Col3 = 'Fran' and
not exists (select 1 from EmpTable e2 where e2.name = 'Frank');
這是一種通用方法,您只需編寫一次每個條件,這將使此查詢不太容易出錯,因此非常易於維護。 但是,這可能是以降低速度為代價的:-)
這個想法與戈登的前兩個查詢中的想法相同:對條件進行排名並選擇排名最佳的比賽。
select *
from emptable
order by case
when Col3 = 'Frank' then 1
when Col3 = 'Fran' then 2
when Col3 like 'Fr%' and col2 like 'J%' then 3
when Col2 like 'J%' then 4
...
end
nulls last
fetch first row with ties;
只需使用ROWNUM = 1:
select * from EmpTable where ROWNUM=1 AND (Col3='Frank' OR Col3='Fran');
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.