一個同事再調試SQL的過程中遇到一個Oracle Not In使用的基本問題,附上SQL:
SELECT vci.cntr_n, voyage.vv_c, co.cntr_n FROM V_CNTR_INSTRUCTION vci ,VOYAGE voyage , cntr_operation co,BERTH_ALLOCATION ba WHERE vci.voyage_out_n = '077' AND voyage.ABBR_VOYAGE_OUT_N = vci.voyage_out_n AND vci.load_vessel_m ='O NEWZEALAND' AND voyage.ABBR_VESSEL_M = vci.load_vessel_m AND ba.VV_C = voyage.VV_C AND co.CNTR_N = vci.CNTR_N AND ba.BERTH_SEQ_N = 1 AND co.LOAD_DT IS NOT NULL AND co.CNTR_N NOT IN (SELECT job.CNTR_N FROM JOB_SEQ job WHERE job.VV_C = voyage.VV_C AND job.OPERATION_C in ('E','R','C','S')) |
他的目的很簡單,就是查出來CNTR_N,並且值不在子查詢中。結果子查詢中確實沒有CNTR_N的值,就是查詢不出來。
調試過程中發現如果用CNTR_N NOT IN ('') 就不會顯示任何值,但是子查詢會返回來一些值,不是因爲返回值爲空影響的。
接着上百度搜索一下NOT IN的用法,發現一句提示:子查詢【select distinct mgr from emp】結果中存在【NULL】值,導致查詢結果失效,於是檢查子查詢的返回結果,發現確實有CNTR_N爲NULL的情況。
問題解決,需要更改子查詢的SQL,使返回值不能返回NULL值,更改如下:
SELECT vci.cntr_n, voyage.vv_c, co.cntr_n
FROM V_CNTR_INSTRUCTION vci ,VOYAGE voyage , cntr_operation co,BERTH_ALLOCATION ba
WHERE vci.voyage_out_n = '077' AND voyage.ABBR_VOYAGE_OUT_N = vci.voyage_out_n
AND vci.load_vessel_m ='O NEWZEALAND' AND voyage.ABBR_VESSEL_M = vci.load_vessel_m
AND ba.VV_C = voyage.VV_C AND co.CNTR_N = vci.CNTR_N AND ba.BERTH_SEQ_N = 1 AND co.LOAD_DT IS NOT NULL
AND co.CNTR_N NOT IN (SELECT job.CNTR_N FROM JOB_SEQ job WHERE job.VV_C = voyage.VV_C
AND job.OPERATION_C in ('E','R','C','S') AND job.CNTR_N IS NOT NULL)