2012-04-05 131 views
1

這裏是查詢有人可以解釋這個查詢

SELECT * FROM customers 
WHERE 
    NOT EXISTS 
    (  
      SELECT 1 FROM brochure_requests  
      WHERE brochure_requests.first_name = customers.customer_first_name AND  
      brochure_requests.last_name = customers.customer_last_name 
    ) 

此查詢工作得很好,但我不知道爲什麼它的工作原理。在NOT EXISTS部分SELECT 1什麼是。當我運行此查詢

select 1 from test2 

這裏是結果:

1 
----- 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
.. 

如何在不存在查詢工作?

回答

3

編譯器足夠聰明,可以忽略EXISTS中的實際SELECT。所以,基本上,如果它會因爲過濾器匹配而返回行,這就是它所關心的...... EXISTSSELECT部分永遠不會執行。它只使用EXISTS子句進行評估

我有這個誤解很長一段時間,因爲你會看到這個SELECT 1很多。但是,我已經看到了42,*等......它從來沒有真正關心結果,只有那裏會有一個:)。要記住的關鍵是SQL是一種編譯語言,所以它會適當地優化它。

你可以放一個1/0,它不會拋出一個零除異常......因此進一步證明結果集不被評估。這在this SQLFiddle

代碼所示,從小提琴:

CREATE TABLE test (i int) 
CREATE TABLE test2 (i int) 

INSERT INTO test VALUES (1) 
INSERT INTO test2 VALUES (1) 

SELECT i 
FROM test 
WHERE EXISTS 
(
    SELECT 1/0 
    FROM test2 
    WHERE test2.i = test.i 
) 

最後,更多的要貴點,在NOT簡單地否定一個EXISTS,說要忽略匹配任何行

+0

Wow..thanks這個交代 – Luke101 2012-04-05 17:04:40

-1

很簡單的檢查,如果存在行,它將返回1,只需檢查它是否存在,僅此而已。

+0

的存在實際上並不返回任何東西。 – 2012-04-05 16:18:52

+0

如果它沒有返回任何東西,它只是表示沒有查詢被匹配,你的查詢條件是常見的「if exists condition」,當我們只需要檢查該行是否存在時,不需要返回某些東西,只檢查是否存在否則,這就是爲什麼子查詢中有一個「1」。 – Elkan 2012-04-05 16:21:14

+0

不,我在說的是EXISTS子查詢實際上並不返回1.它僅僅用作評估的一種手段。請參閱我的答案小提示以獲得證明 – 2012-04-05 16:23:05

1

子查詢是correlated subquery加入所選字段上的customersbrochure_requests表。

EXISTS子句只是一個謂詞,它只返回匹配的行(並且NOT否定那個)。

-1

如果客戶要求提供小冊子,子查詢會爲該客戶返回1。並且不會將此客戶添加到返回結果集中。 NOT EXISTS子句的子集。

+0

子查詢實際上並沒有返回任何東西 – 2012-04-05 16:17:08

-1

注意:我不認識Oracle,也不是SQL方面的專家。

但是,SELECT 1 from只需爲匹配from子句的每一行返回一個1。所以內部select可以找到一個brochure_requests行,其名稱字段與當前正在考慮的customer行的名稱字段相匹配,它將生成1結果,並且失敗NOT EXISTS

因此,查詢選擇所有customers誰沒有匹配他們的名字brochure_request

+0

需要注意的是SELECT部分​​永遠不會被評估,所以它實際上不會產生1 – 2012-04-05 16:30:42

-2

對於表Customers的每一行,查詢返回sub-query時的行。 NOT EXISTS不返回任何行。

如果NOT EXISTS中的子查詢返回行,則表Customers的行不返回。

+0

子查詢實際上並不返回任何東西。它僅用於評估目的 – 2012-04-05 16:45:01

0

查詢:

select 1 from test2 

顯示您作爲在TEST2表中的所有記錄值的值爲1。

每個SELECT查詢必須至少有一列。我認爲這就是爲什麼在這裏使用具有值1的匿名列的原因。

子查詢爲您提供表brochure_requests中相關客戶的行。

NOT EXISTS導致主查詢返回Customers表中的所有行,這些行不在表brochure_requests中。

0

有問題的關係運算符被稱爲'antijoin'(或者'不匹配'或'半差異')。使用自然語言:不匹配使用公共屬性first_name和last_name的brochure_requests的客戶。

密切相關的運算符是關係差異(或者是「減」或「除」),例如在SQL

SELECT customer_last_name, customer_first_name 
    FROM customers 
EXCEPT 
SELECT last_name, first_name 
    FROM brochure_requests; 
相關問題