2015-03-31 40 views
1

我想我對「不存在」的工作有誤解,希望能夠向我澄清。SQL不存在的地方

下面是示例代碼,我運行(也SQL Fiddle

select sum(col1) col1, sum(col2) col1, sum(col3) col3 
from (
    select 1 col1, 1 col2, 1 col3 
    from dual tbl1 
) 
where not exists(
    select 2 col1, 1 col2, 1 col3 
    from dual tbl2 
) 

我認爲它應該返回:

1, 1, 1 

反而它沒有返回。

我做這樣的假設只是一個事實,即我雖然NOT EXISTS會給我所有的第一個查詢沒有在第二個查詢存在行的列表(在這種情況下1,1,1)

  1. 爲什麼這不起作用
  2. 什麼是適當的方式使它按我期待的方式工作?
+1

如果好方法您正在使用SQL Server使用:EXCEPT,在Oracle上:MINUS。 – Horaciux 2015-03-31 19:39:47

回答

5

你在你的NOT EXISTS()條件執行不相關子查詢。它始終返回一行,因此NOT EXISTS條件永遠不會滿足,並且您的查詢返回零行。

Oracle有一個行集差分運算,MINUS,應該做你想要的東西:

select sum(col1) col1, sum(col2) col1, sum(col3) col3 
from (
    select 1 col1, 1 col2, 1 col3 
    from dual tbl1 

    MINUS 

    select 2 col1, 1 col2, 1 col3 
    from dual tbl2 
) 

SQL Server有一個EXCEPT操作,做同樣的事情作爲Oracle的MINUS。其他一些數據庫實現了其中的一個或另一個。

+0

之間的關聯,這是有道理的這就是擴展的真棒+1。你知道如何排除空行(我假設這是由SUM()引起的) – Kairan 2015-03-31 20:01:39

+0

什麼是空行?當我運行我在SQL Fiddle(Oracle 11g R2)中提出的查詢時,我得到一行值爲'(1,1,1)'的行。但是如果你想在某些或所有列中用'NULL'忽略源行,那麼你可以在第一個子查詢中用'WHERE'子句做到這一點。 – 2015-03-31 20:11:18

+0

對不起,我更改了第二個查詢以選擇1,1,1來測試另一個場景,認爲可能會有一些更有魅力的方式排除空行,​​而不是在col1不爲null且col2不爲null且col3不爲null – Kairan 2015-03-31 20:31:29

1

EXISTS僅當結果集中存在記錄時才返回true;它沒有做任何值檢查。由於子查詢返回一條記錄,因此EXISTS爲真,NOT EXISTS爲false,並且結果中沒有記錄。

通常,您在子查詢中有一個WHERE cluase以將值與外部查詢進行比較。

一種方式來完成你想要的是使用EXCEPT

select sum(col1) col1, sum(col2) col1, sum(col3) col3 
from (
    select 1 col1, 1 col2, 1 col3 
    from dual tbl1 
) 
EXCEPT(
    select 2 col1, 1 col2, 1 col3 
    from dual tbl2 
) 
+0

現在,我明白你應該使用兩個表外部查詢和EXISTS/NOT EXISTS – Kairan 2015-03-31 20:03:53

1

一個不存在,包括從雙選擇將不會返回任何東西。不存在將排除嵌入式SQL返回內容的行。一般情況下不存在應選用這樣的:

select ... from MY_TABLE A where not exists (select 1 from OTHER_TABLE B where A.SOME_COL = B.SOME_COL) 
1

由於使用NOT EXISTS是不是因爲它是隻返回單行所以用減號嘗試它除了

select sum(col1) col1, sum(col2) col1, sum(col3) col3 from (select 1 col1, 1 col2, 1 col3 from dual tbl1 MINUS select 2 col1, 1 col2, 1 col3 from dual tbl2) 

select sum(col1) col1, sum(col2) col1, sum(col3) col3 from (select 1 col1, 1 col2, 1 col3 from dual tbl1) EXCEPT(select 2 col1, 1 col2, 1 col3 from dual tbl2)