瞭解一下NULLs怎樣影響IN和EXISTS(轉)
瞭解一下NULLs怎樣影響IN和EXISTS(轉)[@more@] 如果你的資料庫設計在任何一欄中都允許NULL值的話,你需要了解一下,在你的查詢語句中,不同的子句是怎樣對待這一問題的。 從表面上看,可能顯示出這樣的情形,即SQL子句IN與EXISTS可以互換。然而,在處理NULL值時,它們的表現截然不同,而且得到的結果也很可能不同。問題源於這樣一個事實,即在一個Oracle資料庫中,一個NULL值意味著未知,因此,對一個NULL值的任何比較或操作也都是無效的,而任何返回NULL的測試也都被忽視了。例如,以下這些查詢語句都不會返回任何行: select 'true' from dual where 1 = null; select 'true' from dual where 1 != null; 值1既不能說是等於NULL,也不能說是不等於NULL。只有是NULL的時候才會返回一個真正的NULL值並返回一行。 select 'true' from dual where 1 is null; select 'true' from dual where null is null; 當你使用IN時,相當於你告訴SQL接受一個值,並將它與某個清單中使用=的每一個值或一組值進行比較。只要存在了任何NULL值,就不會返回任何行,縱使兩個值都是NULL也不行。 select 'true' from dual where null in (null); select 'true' from dual where (null,null) in ((null,null)); select 'true' from dual where (1,null) in ((1,null)); 一個IN從功能上等同於=ANY子句: select 'true' from dual where null = ANY (null); select 'true' from dual where (null,null) = ANY ((null,null)); select 'true' from dual where (1,null) = ANY ((1,null)); 當你使用一種與EXISTS等同的格式時,SQL會計算行數,卻忽視子查詢中的值,就算你返回NULL也一樣。 select 'true' from dual where exists (select null from dual); select 'true' from dual where exists (select 0 from dual where null is null); 從邏輯上看,IN與EXISTS是一樣的。IN子句在外部查詢中比較子查詢返回的值,並過濾掉行;EXISTS子句在子查詢內部比較那些值並過濾掉行。在出現NULL值的情況下,作為結果而出現的那些行是相同的。 selectename from emp where empno in (select mgr from emp); selectename from emp e where exists (select 0 from emp where mgr = e.empno); 不過,當邏輯被轉變成使用NOT IN和NOT EXISTS時,問題就出現了,這兩個語句會返回不同的行(第一個查詢會返回0行;第二個返回意想的資料-它們是不同的查詢): selectename from emp where empno not in (select mgr from emp); selectename from emp e where not exists (select 0 from emp where mgr =e.empno); NOT IN子句實際上與用=比較每一個值相同,如果任何一個測試為FALSE 或NULL的話,它就會失敗。例如: select 'true' from dual where 1 not in (null,2); select 'true' from dual where 1 != null and 1 != 2; select 'true' from dual where (1,2) not in ((2,3),(2,null)); select 'true' from dual where (1,null) not in ((1,2),(2,3)); 這些查詢不會返回任何行。而第二個更值得懷疑,1!=NULL是NULL,因此對整個WHERE條件來說都是錯誤的。它們會這樣執行: select 'true' from dual where 1 not in (2,3); select 'true' from dual where 1 != 2 and 1 != 3; 只要你在結果中阻止系統返回NULL,在這之前你還是可以使用NOT IN查詢(同樣,這些都能執行,不過我假定empno不是NULL,在我們這個案例中,這是一個很好的假設): selectename from emp where empno not in (select mgr from emp where mgr is not null); selectename from emp where empno not in (select nvl(mgr,0) from emp); 由於瞭解了IN,EXISTS,NOT IN,以及NOT EXISTS之間的差別,當一個子查詢的資料中出現NULL時,你就可以避免一個非常普遍的問題了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10763080/viewspace-948384/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle中的exists和not exists和in用法詳解Oracle
- 騷年,Koa和Webpack瞭解一下?Web
- 影響遊戲ROI的多種因素你都瞭解嗎?遊戲
- 大資料造成的這些影響你未必瞭解大資料
- oracle中的exists 和not exists 用法詳解Oracle
- 瞭解一下Bootstrapboot
- CSS 瞭解一下CSS
- [譯] 帶你瞭解什麼是工程師和工程師的影響力工程師
- 雲端計算發展前景怎麼樣?有哪些影響因素?
- table 元件瞭解一下?元件
- Swift GCD 瞭解一下SwiftGC
- this.$toast() 瞭解一下?AST
- JSX,瞭解一下?JS
- 瞭解一下SQL ServerSQLServer
- [Oracle] exists 和 not existsOracle
- Oralce 使用SQL中的exists 和not exists 用法詳解SQL
- 瞭解CObject 和 CRuntimeClass (轉)Object
- (轉)ORACLE 中IN和EXISTS比較Oracle
- YouGov:缺少多樣性影響廣告效果Go
- 瞭解 ignore_above 引數對 Elasticsearch 中磁碟使用的影響Elasticsearch
- 資料洩密所帶來的影響:一個全面的瞭解
- C#中的explicit和implicit瞭解一下吧C#
- CSS註釋瞭解一下CSS
- async函式,瞭解一下函式
- Immutable.js瞭解一下?JS
- RecyclerView.smoothScrollToPosition瞭解一下View
- React-HOC瞭解一下React
- 木桶佈局,瞭解一下
- 策略模式不瞭解一下?模式
- iOS挖礦瞭解一下?iOS
- react-router瞭解一下React
- require.js瞭解一下UIJS
- 應用層,瞭解一下
- async/await,瞭解一下?AI
- HTTP快取瞭解一下HTTP快取
- Spring和SpringMVC必用註解,乾貨瞭解一下SpringMVC
- oracle中關於in和exists,not in 和 not existsOracle
- (轉)ORACLE 中IN和EXISTS的區別Oracle