9.16. 子查詢資料表達式

本節描述 PostgreSQL 裡面能用的 SQL 兼容的子查詢資料表達式。所有本節中成文的資料表達式都返回布爾值(真/假)結果。

9.16.1. EXISTS

EXISTS ( subquery )

EXISTS 的參數是一個任意的SELECT語句, 或者說子查詢。系統對子查詢進行運算以判斷它是否返回行。 如果它至少返回一行,那麼 EXISTS 的結果就為"真"; 如果子查詢沒有返回行,那麼 EXISTS 的結果是"假"

子查詢可以引用來自周圍的查詢的變量,這些變量在該子查詢的任何一次計算中都起常量的作用。

這個子查詢通常只是執行到能判斷它是否可以生成至少一行為止, 而不是等到全部結束。在這裡寫任何有副作用的子查詢都是不明智的(比如調用序列函數);這些副作用是否發生是很難判斷的。

因為結果只取決於是否會返回行,而不取決於這些行的內容, 所以這個子查詢的輸出列資料表通常是無關緊要的。一個常用的編碼習慣是用下面的形式寫所有的EXISTS測試 EXISTS(SELECT 1 WHERE ...)。不過這條規則有例外, 比如那些使用 INTERSECT 的子查詢。

下面這個簡單的例子類似在col2上的一次內連線,但是它為每個 tab1的行生成最多一個輸出,即使存在多個匹配tab2的行也如此︰

SELECT col1 from tab1
    WHERE EXISTS(SELECT 1 from tab2 WHERE col2 = tab1.col2);

9.16.2. IN

expression IN (subquery)

IN 的這種形式的右手邊是一個圓括弧括起來的子查詢, 它必須只返回一個字串。左手邊資料表達式對子查詢的結果的每一行進行一次計算和比較。 如果找到任何等於子查詢行的情況,那麼 IN 的結果就是"真"。 如果沒有找到相等行,那麼結果是"假"(包括子查詢沒有返回任何行的特殊例子)。

請注意如果左手邊資料表達式生成 NULL,或者沒有相等的右手邊數值, 並且至少有一個右手邊行生成 NULL,那麼 IN 構造的結果將是 NULL,而不是假。 這個行為是遵照 SQL 處理布爾和 NULL 值組合時的規則定的。

EXISTS 一樣,假設子查詢將被完成執行完全是不明智的。

row_constructor IN (subquery)

這種形式的 IN 的左手邊是一個行構造器, 如 Section 4.2.11 裡面所述, 右手邊是一個圓括弧括起來的子查詢,它必須返回和左手邊返回的行中資料表達式所構成的完全一樣多的字串。 左手邊資料表達式就子查詢結果的每一行進行計算很比較。如果找到任意相等的子查詢行,則 IN 的結果為"真"。如果沒有找到相等行, 那麼結果為"假"(包括子查詢不返回行的特殊例子)。

通常,資料表達式或者子查詢行裡的 NULL 是按照 SQL 布爾資料表達式的一般規則進行組合的。 如果兩個行對應的成員都是非空並且相等,那麼認為這兩行相等;如果任意對應成員為非空且不等,那麼該兩行不等; 否則這樣的行比較的結果是未知(NULL)。如果所有行的結果要麼是不等, 要麼是 NULL,並且至少有一個 NULL,那麼 IN 的結果是 NULL。

9.16.3. NOT IN

expression NOT IN (subquery)

右手邊是一個用圓括弧包圍的子查詢,它必須返回一個字串。左手邊資料表達式就子查詢結果的每一行進行計算和比較。 如果只找到不相等的子查詢行(包括子查詢不返回行的特殊情況),那麼NOT IN 的結果是"真"。 如果找到任何相等行,則結果為"假"

請注意如果左手邊資料表達式返回空,或者如果沒有等於右手邊的值,並且至少一個右手邊行生成空, 那麼 NOT IN 構造的結果將是空,而不是真。這是根據 SQL 對布爾和空值組合的一般規則制定的。

EXISTS 一樣,假設子查詢會完全結束是不明智的。

row_constructor NOT IN (subquery)

NOT IN 的這種形式左手邊是一個行構造器, 如 Section 4.2.11 裡所述。其右手邊是一個圓括弧括起來的子查詢, 它必須返回和左手邊資料表達式返回的行一樣多的字串。 左手邊資料表達式對子查詢的結果的每一行進行一次計算和比較。 如果只出現不等於子查詢行的情況,那麼 NOT IN 的結果就是"真"。 (包括子查詢沒有返回任何行的特殊例子)。如果找到相等行,那麼結果是"假"

和通常一樣,資料表達式或者子查詢行裡的 NULL 是按照 SQL 布爾資料表達式的一般規則進行組合的。 如果兩個行對應的成員都是非空並且相等,那麼認為這兩行相等;如果任意對應成員為非空且不等,那麼該兩行不等; 否則這樣的行比較的結果是未知(NULL)。如果所有行的結果要麼是不等, 要麼是 NULL,並且至少有一個 NULL,那麼 NOT IN 的結果是 NULL。

9.16.4. ANY/SOME

expression operator ANY (subquery)
expression operator SOME (subquery)

這種形式的 ANY 右手邊是一個圓括弧括起來的子查詢, 它必須返回一個字串。左手邊資料表達式將使用給出的 operator對子查詢的結果的每一行進行一次計算和比較。 目前如果獲得任何真值結果,那麼 ANY 的結果就是"真"。 如果沒有找到真值結果,那麼結果是"假"(包括子查詢沒有返回任何行的特殊例子)。

SOMEANY 的同意詞。 IN 等效於 = ANY

請注意如果沒有任何成功並且至少有一個右手邊行為該操作符結果生成 NULL, 那麼 ANY 構造的結果將是 NULL,而不是 FALSE。 這個行為是遵照 SQL 處理布爾和 NULL 值組合時的規則定的。

EXISTS 一樣,假設子查詢將被完成執行完全是不明智的。

row_constructor operator ANY (subquery)
row_constructor operator SOME (subquery)

的這種形式的左手邊是一個行構造器,如 Section 4.2.11 裡描述的那樣。 右手邊是一個圓括弧括起來的子查詢, 它必須返回和左手邊列資料表給出的資料表達式一樣多的列。左手邊資料表達式將使用給出的 operator對子查詢的結果的每一行進行一次計算和比較。 目前,系統只允許使用 =<> 操作符處理逐行的 ANY 構造。 如果分別找到相等或者不相等的行,那麼 ANY 的結果就是 "真"。如果沒有找到這樣的行,那麼結果是"假"(包括子查詢沒有返回任何行的特殊例子)。

通常,資料表達式或者子查詢行裡的 NULL 是按照 SQL 布爾資料表達式的一般規則進行組合的。 如果兩個行對應的成員都是非空並且相等,那麼認為這兩行相等;如果任意對應成員為非空且不等,那麼該兩行不等; 否則這樣的行比較的結果是未知(NULL)。如果至少有一個 NULL 行結果, 那麼 ANY 的結果將是TRUE 或者 NULL。

9.16.5. ALL

expression operator ALL(subquery)

ALL 的這種形式的右手邊是一個圓括弧括起來的子查詢, 它必須只返回一列。左手邊資料表達式將使用給出的 operator對子查詢的結果的每一行進行一次計算和比較。該操作符必須生成布爾結果。 如果所有行的結果都為"真",(包括子查詢沒有返回任何行的特殊例子)。 那麼 ALL 的結果就是"真"。如果沒有存在任何假值結果,那麼結果是"假"

NOT IN 等效於 <> ALL

請注意如果沒有運算失敗但是至少有一個右手邊行為該操作符的結果生成 NULL 值, 那麼 ALL 構造的結果將是 NULL,而不是 TRUE。 這個行為是遵照 SQL 處理布爾和 NULL 值組合時的一般規則定的。

EXISTS 一樣,假設子查詢將被完成執行完全是不明智的。

row_constructor operator ALL (subquery)

ALL 的這種形式的左手邊是一個行構造器,如 Section 4.2.11 所述。 右手邊是一個圓括弧括起來的子查詢,它必須返回和左手邊行給出的資料表達式一樣多的字串。 左手邊資料表達式將使用給出的 operator對子查詢的結果的每一行進行一次計算和比較。 目前系統只允許使用 =<> 操作符處理逐行的 ALL 查詢。 如果所有子查詢都是相等或者不相等的行,那麼 ALL 的結果就是"真"。(包括子查詢沒有返回任何行的特殊例子)。 如果分別有任何不相等或者相等的行,那麼結果是"假"

通常,資料表達式或者子查詢行裡的 NULL 是按照 SQL 布爾資料表達式的一般規則 進行組合的。如果兩個行對應的成員都是非空並且相等,那麼認為這兩行 相等;如果任意對應成員為非空且不等,那麼該兩行不等; 否則這樣的行比較的結果是未知(NULL)。如果至少有一個 NULL 行結果, 那麼 ALL 的結果就不可能是TRUE;它將會是 FALSE 或者 NULL。

9.16.6. 逐行比較

row_constructor operator (subquery)

左手邊是一個行構造器,如 Section 4.2.11 所述。 右手邊是一個圓括弧括起來的子查詢,該查詢必須返回很左手邊資料表達式數目完全一樣的字串。 另外,該子查詢不能返回超過一行的數量。(如果它返回零行,那麼結果就是 NULL。) 左手邊逐行與右手邊的子查詢結果行,或者右手邊資料表達式列資料表進行比較。目前,只允許使用 =<> 操作符進行逐行比較。如果兩行分別是相等或者不等,那麼結果為"真"

通常,資料表達式或者子查詢行裡的 NULL 是按照 SQL 布爾資料表達式的一般規則進行組合的。 如果兩個行對應的成員都是非空並且相等,那麼認為這兩行相等;如果任意對應成員為非空且不等,那麼該兩行不等; 否則這樣的行比較的結果是未知(NULL)。