PostgreSQL 子查詢(xún)表達(dá)式

2021-08-27 10:37 更新
9.23.1. EXISTS
9.23.2. IN
9.23.3. NOT IN
9.23.4. ANY/SOME
9.23.5. ALL
9.23.6. 單一行比較

本節(jié)描述PostgreSQL中可用的SQL兼容的子查詢(xún)表達(dá)式。所有本節(jié)中成文的表達(dá)式都返回布爾值(真/假)結(jié)果。

9.23.1. EXISTS

EXISTS (subquery)

EXISTS的參數(shù)是一個(gè)任意的SELECT語(yǔ)句, 或者說(shuō)子查詢(xún)。系統(tǒng)對(duì)子查詢(xún)進(jìn)行運(yùn)算以判斷它是否返回行。如果它至少返回一行,那么EXISTS的結(jié)果就為; 如果子查詢(xún)沒(méi)有返回行,那么 EXISTS的結(jié)果是。

子查詢(xún)可以引用來(lái)自周?chē)牟樵?xún)的變量,這些變量在該子查詢(xún)的任何一次計(jì)算中都起常量的作用。

這個(gè)子查詢(xún)通常只是運(yùn)行到能判斷它是否可以返回至少一行為止, 而不是等到全部結(jié)束。在這里寫(xiě)任何有副作用的子查詢(xún)都是不明智的(例如調(diào)用序列函數(shù));這些副作用是否發(fā)生是很難判斷的。

因?yàn)榻Y(jié)果只取決于是否會(huì)返回行,而不取決于這些行的內(nèi)容, 所以這個(gè)子查詢(xún)的輸出列表通常是無(wú)關(guān)緊要的。一個(gè)常用的編碼習(xí)慣是用EXISTS(SELECT 1 WHERE ...)的形式寫(xiě)所有的EXISTS測(cè)試。不過(guò)這條規(guī)則有例外,例如那些使用INTERSECT的子查詢(xún)。

下面這個(gè)簡(jiǎn)單的例子類(lèi)似在col2上的一次內(nèi)聯(lián)接,但是它為每個(gè) tab1的行生成最多一個(gè)輸出,即使存在多個(gè)匹配tab2的行也如此∶

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

9.23.2. IN

expression IN (subquery)

右手邊是一個(gè)圓括弧括起來(lái)的子查詢(xún), 它必須正好只返回一個(gè)列。左手邊表達(dá)式將被計(jì)算并與子查詢(xún)結(jié)果逐行進(jìn)行比較。 如果找到任何等于子查詢(xún)行的情況,那么IN的結(jié)果就是。 如果沒(méi)有找到相等行,那么結(jié)果是(包括子查詢(xún)沒(méi)有返回任何行的情況)。

請(qǐng)注意如果左手邊表達(dá)式得到空值,或者沒(méi)有相等的右手邊值, 并且至少有一個(gè)右手邊行得到空值,那么IN結(jié)構(gòu)的結(jié)果將是空值,而不是假。這個(gè)行為是遵照 SQL 處理空值的一般規(guī)則的。

EXISTS一樣,假設(shè)子查詢(xún)將被完成運(yùn)行完全是不明智的。

row_constructor IN (subquery)

這種形式的IN的左手邊是一個(gè)行構(gòu)造器, 如第 4.2.13 節(jié)中所述。 右手邊是一個(gè)圓括弧子查詢(xún),它必須返回和左手邊返回的行中表達(dá)式所構(gòu)成的完全一樣多的列。 左手邊表達(dá)式將被計(jì)算并與子查詢(xún)結(jié)果逐行進(jìn)行比較。如果找到任意相等的子查詢(xún)行,則 IN的結(jié)果為。如果沒(méi)有找到相等行, 那么結(jié)果為(包括子查詢(xún)不返回行的情況)。

通常,表達(dá)式或者子查詢(xún)行里的空值是按照 SQL 布爾表達(dá)式的一般規(guī)則進(jìn)行組合的。 如果兩個(gè)行對(duì)應(yīng)的成員都非空并且相等,那么認(rèn)為這兩行相等;如果任意對(duì)應(yīng)成員為非空且不等,那么這兩行不等; 否則這樣的行比較的結(jié)果是未知(空值)。如果所有行的結(jié)果要么是不等, 要么是空值,并且至少有一個(gè)空值,那么IN的結(jié)果是空值。

9.23.3. NOT IN

expression NOT IN (subquery)

右手邊是一個(gè)用圓括弧包圍的子查詢(xún),它必須返回正好一個(gè)列。左手邊表達(dá)式將被計(jì)算并與子查詢(xún)結(jié)果逐行進(jìn)行比較。 如果只找到不相等的子查詢(xún)行(包括子查詢(xún)不返回行的情況),那么NOT IN的結(jié)果是。 如果找到任何相等行,則結(jié)果為。

請(qǐng)注意如果左手邊表達(dá)式得到空值,或者沒(méi)有相等的右手邊值, 并且至少有一個(gè)右手邊行得到空值,那么NOT IN結(jié)構(gòu)的結(jié)果將是空值,而不是真。這個(gè)行為是遵照 SQL 處理空值的一般規(guī)則的。

EXISTS一樣,假設(shè)子查詢(xún)會(huì)完全結(jié)束是不明智的。

row_constructor NOT IN (subquery)

這種形式的NOT IN的左手邊是一個(gè)行構(gòu)造器, 如第 4.2.13 節(jié)中所述。 右手邊是一個(gè)圓括弧子查詢(xún),它必須返回和左手邊返回的行中表達(dá)式所構(gòu)成的完全一樣多的列。 左手邊表達(dá)式將被計(jì)算并與子查詢(xún)結(jié)果逐行進(jìn)行比較。如果找到不等于子查詢(xún)行的行,則 NOT IN的結(jié)果為。如果找到相等行, 那么結(jié)果為(包括子查詢(xún)不返回行的情況)。

通常,表達(dá)式或者子查詢(xún)行里的空值是按照 SQL 布爾表達(dá)式的一般規(guī)則進(jìn)行組合的。 如果兩個(gè)行對(duì)應(yīng)的成員都非空并且相等,那么認(rèn)為這兩行相等;如果任意對(duì)應(yīng)成員為非空且不等,那么這兩行不等; 否則這樣的行比較的結(jié)果是未知(空值)。如果所有行的結(jié)果要么是不等, 要么是空值,并且至少有一個(gè)空值,那么NOT IN的結(jié)果是空值。

9.23.4. ANY/SOME

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

這種形式的右手邊是一個(gè)圓括弧括起來(lái)的子查詢(xún), 它必須返回正好一個(gè)列。左手邊表達(dá)式將被計(jì)算并使用給出的 操作符對(duì)子查詢(xún)結(jié)果逐行進(jìn)行比較。如果獲得任何真值結(jié)果,那么ANY的結(jié)果就是。 如果沒(méi)有找到真值結(jié)果,那么結(jié)果是(包括子查詢(xún)沒(méi)有返回任何行的情況)。

SOMEANY的同義詞。IN等價(jià)于= ANY。

請(qǐng)注意如果沒(méi)有任何成功并且至少有一個(gè)右手邊行為該操作符結(jié)果生成空值, 那么ANY結(jié)構(gòu)的結(jié)果將是空值,而不是假。 這個(gè)行為是遵照 SQL 處理空值布爾組合的一般規(guī)則制定的。

EXISTS一樣,假設(shè)子查詢(xún)將被完全運(yùn)行是不明智的。

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

這種形式的左手邊是一個(gè)行構(gòu)造器,如第 4.2.13 節(jié)所述。右手邊是一個(gè)圓括弧括起來(lái)的子查詢(xún), 它必須返回和左手邊列表給出的表達(dá)式一樣多的列。左手邊表達(dá)式將被計(jì)算并使用給出的操作符對(duì)子查詢(xún)結(jié)果逐行進(jìn)行比較。如果比較為任何子查詢(xún)行返回真,則 ANY的結(jié)果為。如果比較對(duì)每一個(gè)子查詢(xún)行都返回假,則結(jié)果為(包括子查詢(xún)不返回行的情況)。如果比較不對(duì)任何行返回真并且至少對(duì)一行返回 NULL,則結(jié)果為 NULL。

關(guān)于行構(gòu)造器比較的詳細(xì)含義請(qǐng)見(jiàn)第 9.24.5 節(jié)。

9.23.5. ALL

expression operator ALL (subquery)

ALL 的這種形式的右手邊是一個(gè)圓括弧括起來(lái)的子查詢(xún), 它必須只返回一列。左手邊表達(dá)式將被計(jì)算并使用給出的 操作符對(duì)子查詢(xún)結(jié)果逐行進(jìn)行比較。該操作符必須生成布爾結(jié)果。 如果所有行得到真(包括子查詢(xún)沒(méi)有返回任何行的情況),ALL的結(jié)果就是。如果沒(méi)有存在任何假值結(jié)果,那么結(jié)果是 。如果比較為任何行都不返回假并且對(duì)至少一行返回 NULL,則結(jié)果為 NULL。

NOT IN等價(jià)于<> ALL。

EXISTS一樣,假設(shè)子查詢(xún)將被完全運(yùn)行是不明智的。

row_constructor operator ALL (subquery)

ALL的這種形式的左手邊是一個(gè)行構(gòu)造器,如第 4.2.13 節(jié)所述。 右手邊是一個(gè)圓括弧括起來(lái)的子查詢(xún),它必須返回和左手邊行中表達(dá)式一樣多的列。 左手邊表達(dá)式將被計(jì)算并使用給出的 操作符對(duì)子查詢(xún)結(jié)果逐行進(jìn)行比較。如果對(duì)所有子查詢(xún)行該比較都返回真,那么 ALL的結(jié)果就是(包括子查詢(xún)沒(méi)有返回任何行的情況)。如果對(duì)任何子查詢(xún)行比較返回假,則結(jié)果為。如果比較對(duì)任何子查詢(xún)行都不返回假并且對(duì)至少一行返回 NULL,則結(jié)果為 NULL。

關(guān)于行構(gòu)造器比較的詳細(xì)含義請(qǐng)見(jiàn)第 9.24.5 節(jié)。

9.23.6. 單一行比較

row_constructor operator (subquery)

左手邊是一個(gè)行構(gòu)造器,如第 4.2.13 節(jié)所述。 右手邊是一個(gè)圓括弧括起來(lái)的子查詢(xún),該查詢(xún)必須返回和左手邊行中表達(dá)式數(shù)目完全一樣的列。 另外,該子查詢(xún)不能返回超過(guò)一行的數(shù)量(如果它返回零行,那么結(jié)果就是空值)。 左手邊被計(jì)算并逐行與右手邊的子查詢(xún)結(jié)果行比較。

關(guān)于行構(gòu)造器比較的詳細(xì)含義請(qǐng)見(jiàn)第 9.24.5 節(jié)。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)