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,而不是 FALSE.這個行為是遵照 SQL 處理布爾和 NULL 值組合時的規則定的.

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

(expression, expression[, ...]) IN (subquery)

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

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

9.16.3. NOT IN

expression NOT IN (subquery)

NOT IN 的這種形式的右手邊是一個圓括弧括起來的子查詢, 它必須只返回一列.左手邊表達式對子查詢的結果的每一行進行一次計算和 比較.如果只出現不等于子查詢行的情況,那麼 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 一樣,假設子查詢將被完成運行完全是不明智的.

(expression [, expression ...]) operator ANY (subquery)
(expression [, expression ...]) operator SOME (subquery)

ANY 的這種形式的右手邊是一個圓括弧括起來的子查詢, 它必須返回和左手邊列表給出的表達式一樣多的列.左手邊表達式將使用給出的 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 一樣,假設子查詢將被完成運行完全是不明智的.

(expression, expression[, ...]) operator ALL (subquery)

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

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

9.16.6. 逐行比較

(expression [, expression ...]) operator (subquery)

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

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