国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

了解一下NULLs怎樣影響IN和exists

2024-07-21 02:06:20
字體:
來源:轉載
供稿:網友


如果你的數據庫設計在任何一欄中都允許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時,你就可以避免一個非常普遍的問題了。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 卢氏县| 镇雄县| 璧山县| 军事| 安达市| 莱州市| 漯河市| 张掖市| 晋江市| 黔西| 南昌县| 东阿县| 沁水县| 永定县| 铜鼓县| 安阳市| 曲水县| 沂南县| 建宁县| 竹北市| 通许县| 南乐县| 大连市| 嫩江县| 诸城市| 洞口县| 华亭县| 磐石市| 吉首市| 沙坪坝区| 澳门| 平阴县| 牟定县| 自治县| 英超| 汉源县| 淄博市| 阜新| 汝南县| 天水市| 龙胜|