日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【原创】关于not in的一些事情

發布時間:2024/3/24 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【原创】关于not in的一些事情 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

早上到公司,收到一條cocall消息,是某哥們遇到的疑惑,可能很多新手并不知情:

請教個問題 我執行 1. select * from t_htgl_htpswj t where t.c_wjmc = '山西'; 結果是 存在一條記錄 2. select * from t_htgl_fj t where t.c_wjmc = '山西'; 結果是不存在記錄 3. 為什么執行select count(*) from t_htgl_htpswj htpswj where htpswj.c_wjmc not in (select fj.c_wjmc from t_htgl_fj fj ) 按照 1,2的執行結果,3的結果應該是至少是1才對呀,為什么實際執行結果是0呢。。。。 C_WJMC的類型都是VARCHAR(200) 很詭異的是 第三個查詢,我如果用下面這個語句統計查詢又是可以查詢到結果的。。。。 select count(*) from t_htgl_htpswj htpswj where htpswj.c_wjmc not in (select fj.c_wjmc from t_htgl_fj fj where fj.n_xsxm_htps is not null) 我添加的這個子查詢的條件好像和整體查詢沒有關系呀。。。

對于這個問題,需要了解以下兩點內容:
1.null到底是個什么東西?
2.not in是如何執行的,什么原理?
下面看第一點:
1.null到底是個什么東西?我們知道在存儲過程中:select a into b from t1 where c='';--如果返回的記錄為零,那么會報錯,此時實際上返回的就是一個null,一般在前面加一個count的判斷再into。
null在oracle中代表什么都不是,空記錄,這個地球人都知道,關鍵是在運算中,null和任何值的算術或者邏輯運算結果都是null,而且它和任何值都不相等,也非不相等,和自身也不相等,如:
select * from t1 where a=null;--查不到正確的記錄
select * from t1 where null=null;--查不到記錄。因此在判斷空與非空時使用is null或者is not null來判斷,以下是有個哥們讓優化sql

.......... union all select C_BH,N_AJLB,C_AH,C_AJJC,C_AJMC,C_BH_SAR,D_BJRQ,C_BH_CBDW from t_ywgy_hztj_aj where n_ajlb = 202 and C_TBLX <> null union all select C_BH,N_AJLB,C_AH,C_AJJC,C_AJMC,C_BH_SAR,D_BJRQ,C_BH_CBDW from t_ywgy_hztj_aj where n_ajlb = 302 and C_TBLX <> null ...........

這樣寫是不對的,會獲取不到正確的記錄。應該這樣寫:
select * from t1 where a is null or b is not null;

插播一點,is null和is not null判斷都是無法使用索引的,tom的書上有個很不錯的提議,就是將null以一個值來代替,如果某列代碼值為空,如不妨以-1來代表null,字符的話也可以以其他值(如‘null’)代替,這樣在判斷的時候可以使用索引。
2.not in 是如何執行的?
先看in是如何執行的:
如:

select * from t where a in(1,2,3);查詢等價于: select * from t where a=1 or a=2 or a=3;

如果條件有null呢?

select * from t where a in(1,2,3,null);等價于: select * from t where a=1 or a=2 or a=3 or a=null; --這是沒有問題的,一般一樣可以得到正確結果,因為a和null不相等,因此null值會被忽略

那么not in呢?

select * from t where a not in(1,2,3);--等價于 select * from t where a !=1 and a!=2 and a!=3;

如果這個條件中有null值呢?

select * from t where a not in(1,2,3,null);--等價于 select * from t where a !=1 and a!=2 and a!=3 and a!=null;

看a!=null,這個條件是不成立的,始終都是false,所以導致整個表達式為false,所以查不到任何記錄。

回到開頭的問題:

select count(*) from t_htgl_htpswj htpswj where htpswj.c_wjmc not in (select fj.c_wjmc from t_htgl_fj fj );

"select fj.c_wjmc from t_htgl_fj fj",這個sql中c_wjmc返回的結果是否包含null值呢?
我們執行以下sql:
select count(*) from t_htgl_fj fj where fj.c_wjmc is null;
----------
COUNT(*)
30
----------
所以,子查詢中的c_wjmc存在null值,導致整個where的邏輯運算結果為false,因此沒有返回任何結果。
那么為什么

select count(*) from t_htgl_htpswj htpswj where htpswj.c_wjmc not in (select fj.c_wjmc from t_htgl_fj fj where fj.n_xsxm_htps is not null)”查詢就能返回結果呢?

select fj.c_wjmc from t_htgl_fj fj where fj.n_xsxm_htps is not null;--這個查詢中c_wjmc有沒有空值呢?
執行以下查詢:

select count(*) from thims.t_htgl_fj fj where fj.n_xsxm_htps is not null and c_wjmc is null;--n_xsxm_htps為空且c_wjmc也為空的記錄: ---------- COUNT(*) 0 ----------

這個查詢中恰巧n_xsxm_htps is not null將所有的c_wjmc為null的記錄過濾掉了,所以子查詢中沒有null值,所以能查到正確的結果。

結論:在not in的查詢中,如果子查詢結果中包含null值,將查不到記錄,not in無法處理null值。因此可以使用exists,如果非要使用not in,也要保證在子查詢中將null值過濾掉。
通常情況下,exists效率要高于in,而且exists可以準確的處理null值(其實是事先過濾掉罷了,不再贅述),關于exists和in的使用場景和區別,見另一篇帖子:

轉載于:https://www.cnblogs.com/zhangxsh/p/3494414.html

總結

以上是生活随笔為你收集整理的【原创】关于not in的一些事情的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。