支援的版本:目前 (17) / 16 / 15 / 14 / 13
開發版本:devel
不支援的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2

9.24. 子查詢表達式 #

本節描述了SQL-相容的子查詢表達式,這些表達式可在 PostgreSQL 中使用。 本節中記錄的所有表達式形式都傳回布林值(true/false)結果。

9.24.1. EXISTS #

EXISTS (subquery)

EXISTS 的引數是一個任意的 SELECT 陳述式,或稱作子查詢。 子查詢會被評估以確定它是否傳回任何列。 如果它傳回至少一列,則 EXISTS 的結果為 true; 如果子查詢未傳回任何列,則 EXISTS 的結果為 false

子查詢可以參考周圍查詢中的變數,這些變數在子查詢的任何一次評估期間都將充當常數。

通常,子查詢的執行僅需確定是否傳回至少一列,而無需一直執行到完成。 編寫具有副作用(例如呼叫序列函數)的子查詢是不明智的; 是否會發生副作用可能是無法預測的。

由於結果僅取決於是否傳回任何列,而不取決於這些列的內容,因此子查詢的輸出列表通常並不重要。 一種常見的編碼慣例是以 EXISTS(SELECT 1 WHERE ...) 的形式編寫所有 EXISTS 測試。 但是,也有例外情況,例如使用 INTERSECT 的子查詢。

這個簡單的範例類似於在 col2 上的內部聯結,但它最多為每個 tab1 列產生一個輸出列,即使存在多個匹配的 tab2 列也是如此

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

9.24.2. IN #

expression IN (subquery)

右側是一個帶括號的子查詢,必須正好傳回一列。評估左側的表達式並將其與子查詢結果的每一列進行比較。如果找到任何相等的子查詢列,則 IN 的結果為 true。如果沒有找到相等的列(包括子查詢不傳回任何列的情況),則結果為 false

請注意,如果左側的表達式產生 null,或者如果沒有相等的右側值且至少有一個右側列產生 null,則 IN 構造的結果將為 null,而不是 false。這符合 SQL 對 null 值的布林組合的常規規則。

EXISTS 一樣,假設子查詢會被完全評估是不明智的。

row_constructor IN (subquery)

此形式的 IN 的左側是一個列構造函數,如第 4.2.13 節中所述。 右側是一個帶括號的子查詢,必須正好傳回與左側列中的表達式一樣多的列。 評估左側的表達式並將其逐列與子查詢結果的每一列進行比較。 如果找到任何相等的子查詢列,則 IN 的結果為 true。 如果沒有找到相等的列(包括子查詢不傳回任何列的情況),則結果為 false

與往常一樣,列中的 null 值會根據 SQL 布林表達式的常規規則進行組合。 如果列的所有對應成員都非 null 且相等,則認為兩列相等; 如果任何對應成員為非 null 且不相等,則列不相等; 否則,該列比較的結果未知(null)。 如果所有逐列結果都不相等或為 null,且至少有一個 null,則 IN 的結果為 null。

9.24.3. NOT IN #

expression NOT IN (subquery)

右側是一個帶括號的子查詢,必須正好傳回一列。 評估左側的表達式並將其與子查詢結果的每一列進行比較。 如果僅找到不相等的子查詢列(包括子查詢不傳回任何列的情況),則 NOT IN 的結果為 true。 如果找到任何相等的列,則結果為 false

請注意,如果左側的運算式產生 null,或者如果沒有相等的右側值,且至少有一個右側資料列產生 null,則 NOT IN 結構的結果將為 null,而不是 true。這符合 SQL 對於 null 值的布林組合的標準規則。

EXISTS 一樣,假設子查詢會被完全評估是不明智的。

row_constructor NOT IN (subquery)

此形式的 NOT IN 的左側是一個資料列建構子,如第 4.2.13 節中所述。右側是一個帶括號的子查詢,它必須回傳與左側資料列中運算式數量完全相同的欄位數。左側的運算式會被求值,並以逐列方式與子查詢結果的每一列進行比較。如果只找到不相等的子查詢資料列(包括子查詢未回傳任何資料列的情況),則 NOT IN 的結果為 true。如果找到任何相等的資料列,則結果為 false

與往常一樣,資料列中的 null 值會根據 SQL 布林運算式的標準規則進行組合。如果它們所有對應的成員都是非 null 且相等,則認為兩個資料列相等;如果任何對應的成員是非 null 且不相等,則這些資料列不相等;否則,該資料列比較的結果是未知的 (null)。如果所有逐列結果都是不相等或 null,且至少有一個 null,則 NOT IN 的結果為 null。

9.24.4. ANY/SOME #

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

右側是一個帶括號的子查詢,它必須回傳恰好一個欄位。左側的運算式會被求值,並使用給定的 operator 與子查詢結果的每一列進行比較,operator 必須產生布林結果。如果獲得任何 true 的結果,則 ANY 的結果為 true。如果沒有找到 true 的結果(包括子查詢未回傳任何資料列的情況),則結果為 false

SOMEANY 的同義詞。IN 等同於 = ANY

請注意,如果沒有成功且至少有一個右側資料列為運算子的結果產生 null,則 ANY 結構的結果將為 null,而不是 false。這符合 SQL 對於 null 值的布林組合的標準規則。

EXISTS 一樣,假設子查詢會被完全評估是不明智的。

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

此形式的 ANY 的左側是一個資料列建構子,如第 4.2.13 節中所述。右側是一個帶括號的子查詢,它必須回傳與左側資料列中運算式數量完全相同的欄位數。左側的運算式會被求值,並使用給定的 operator 以逐列方式與子查詢結果的每一列進行比較。如果比較為任何子查詢資料列回傳 true,則 ANY 的結果為 true。如果比較為每個子查詢資料列回傳 false(包括子查詢未回傳任何資料列的情況),則結果為 false。如果與子查詢資料列的比較都沒有回傳 true,且至少有一個比較回傳 NULL,則結果為 NULL。

有關資料列建構子比較的意義的詳細資訊,請參閱第 9.25.5 節

9.24.5. ALL #

expression operator ALL (subquery)

右側是一個帶括號的子查詢,它必須回傳恰好一個欄位。左側的運算式會被求值,並使用給定的 operator 與子查詢結果的每一列進行比較,operator 必須產生布林結果。如果所有資料列都回傳 true(包括子查詢未回傳任何資料列的情況),則 ALL 的結果為 true。如果找到任何 false 的結果,則結果為 false。如果與子查詢資料列的比較都沒有回傳 false,且至少有一個比較回傳 NULL,則結果為 NULL。

NOT IN 等同於 <> ALL

EXISTS 一樣,假設子查詢會被完全評估是不明智的。

row_constructor operator ALL (subquery)

此形式的 ALL 的左側是一個資料列建構子,如第 4.2.13 節中所述。右側是一個帶括號的子查詢,它必須回傳與左側資料列中運算式數量完全相同的欄位數。左側的運算式會被求值,並使用給定的 operator 以逐列方式與子查詢結果的每一列進行比較。如果比較為所有子查詢資料列回傳 true(包括子查詢未回傳任何資料列的情況),則 ALL 的結果為 true。如果比較為任何子查詢資料列回傳 false,則結果為 false。如果與子查詢資料列的比較都沒有回傳 false,且至少有一個比較回傳 NULL,則結果為 NULL。

有關資料列建構子比較的意義的詳細資訊,請參閱第 9.25.5 節

9.24.6. 單列比較 #

row_constructor operator (subquery)

左側是一個資料列建構子,如第 4.2.13 節中所述。右側是一個帶括號的子查詢,它必須回傳與左側資料列中運算式數量完全相同的欄位數。此外,子查詢不能回傳多個資料列。(如果它回傳零個資料列,則結果被視為 null。)左側會被求值,並以逐列方式與單個子查詢結果資料列進行比較。

有關資料列建構子比較的意義的詳細資訊,請參閱第 9.25.5 節

提交更正

如果您在文件中發現任何不正確、與您使用特定功能的經驗不符或需要進一步澄清的地方,請使用此表格來報告文件問題。