PostgreSQL 條件表達(dá)式

2021-08-27 10:21 更新
9.18.1. CASE
9.18.2. COALESCE
9.18.3. NULLIF
9.18.4. GREATESTLEAST

本節(jié)描述在PostgreSQL中可用的SQL兼容的條件表達(dá)式。

提示

如果你的需求超過這些條件表達(dá)式的能力,你可能會希望用一種更富表現(xiàn)力的編程語言寫一個(gè)服務(wù)器端函數(shù)。

注意

盡管COALESCE、GREATESTLEAST在語法上類似于函數(shù),但它們不是普通的函數(shù),因此不能使用顯式VARIADIC數(shù)組參數(shù)。

9.18.1. CASE

SQL CASE表達(dá)式是一種通用的條件表達(dá)式,類似于其它編程語言中的 if/else 語句:

CASE WHEN condition THEN result
     [WHEN ...]
     [ELSE result]
END

CASE子句可以用于任何表達(dá)式可以出現(xiàn)的地方。每一個(gè)condition是一個(gè)返回boolean結(jié)果的表達(dá)式。如果結(jié)果為真,那么CASE表達(dá)式的結(jié)果就是符合條件的result,并且剩下的 CASE表達(dá)式不會被處理。如果條件的結(jié)果不為真,那么以相同方式搜尋任何隨后的WHEN子句。如果沒有WHEN condition為真,那么CASE表達(dá)式的值就是在ELSE子句里的result。如果省略了 ELSE子句而且沒有條件為真,結(jié)果為空。

例子:

SELECT * FROM test;

 a
---
 1
 2
 3


SELECT a,
       CASE WHEN a=1 THEN 'one'
            WHEN a=2 THEN 'two'
            ELSE 'other'
       END
    FROM test;

 a | case
---+-------
 1 | one
 2 | two
 3 | other

所有result表達(dá)式的數(shù)據(jù)類型都必須可以轉(zhuǎn)換成單一的輸出類型。 參閱第 10.5 節(jié)獲取細(xì)節(jié)。

下面這個(gè)簡單形式的CASE表達(dá)式是上述通用形式的一個(gè)變種:

CASE expression
    WHEN value THEN result
    [WHEN ...]
    [ELSE result]
END

第一個(gè)expression會被計(jì)算,然后與所有在WHEN子句中的每一個(gè)value對比,直到找到一個(gè)相等的。如果沒有找到匹配的,則返回在ELSE子句中的result(或者控制)。 這類似于 C 里的switch語句。

上面的例子可以用簡單CASE語法來寫:

SELECT a,
       CASE a WHEN 1 THEN 'one'
              WHEN 2 THEN 'two'
              ELSE 'other'
       END
    FROM test;

 a | case
---+-------
 1 | one
 2 | two
 3 | other

CASE表達(dá)式并不計(jì)算任何無助于判斷結(jié)果的子表達(dá)式。例如,下面是一個(gè)可以避免被零除錯(cuò)誤的方法:

SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END;

注意

第 4.2.14 節(jié)中所述,在有幾種情況中一個(gè)表達(dá)式的子表達(dá)式 會被計(jì)算多次,因此CASE只計(jì)算必要的表達(dá)式這 一原則并非不可打破。例如一個(gè)常量子表達(dá)式 1/0通常將會在規(guī)劃時(shí)導(dǎo)致一次 除零錯(cuò)誤,即便它位于一個(gè)執(zhí)行時(shí)永遠(yuǎn)也不會進(jìn)入的CASE分支時(shí)也是 如此。

9.18.2. COALESCE

COALESCE(value [, ...])

COALESCE函數(shù)返回它的第一個(gè)非空參數(shù)的值。當(dāng)且僅當(dāng)所有參數(shù)都為空時(shí)才會返回空。它常用于在為顯示目的檢索數(shù)據(jù)時(shí)用缺省值替換空值。例如:

SELECT COALESCE(description, short_description, '(none)') ...

如果description不為空,這將會返回它的值,否則如果short_description非空則返回short_description的值,如果前兩個(gè)都為空則返回(none)。

所有參數(shù)都必須轉(zhuǎn)換為一個(gè)公共數(shù)據(jù)類型,它將是結(jié)果的類型 (詳請參見 第 10.5 節(jié) )。

CASE表達(dá)式一樣,COALESCE將不會 計(jì)算無助于判斷結(jié)果的參數(shù);也就是說,在第一個(gè)非空參數(shù)右邊的參數(shù)不會被計(jì)算。這個(gè) SQL 標(biāo)準(zhǔn)函數(shù)提供了類似于NVLIFNULL的能力,它們被用在某些其他數(shù)據(jù)庫系統(tǒng)中。

9.18.3. NULLIF

NULLIF(value1, value2)

當(dāng)value1value2相等時(shí),NULLIF返回一個(gè)空值。 否則它返回value1。 這些可以用于執(zhí)行前文給出的COALESCE例子的逆操作:

SELECT NULLIF(value, '(none)') ...

在這個(gè)例子中,如果value(none),將返回空值,否則返回value的值。

這兩個(gè)參數(shù)必須具有可比較的類型。具體來說,它們的比較與你寫的 value1 = value2 完全一樣,因此必須有一個(gè)合適的=操作符可用。

結(jié)果的類型與第一個(gè)參數(shù)相同,但有一點(diǎn)細(xì)微的區(qū)別。實(shí)際上返回的是隱含 =操作符的第一個(gè)參數(shù),在某些情況下,它將被提升以匹配第二個(gè)參數(shù)的類型。 例如,NULLIF(1, 2.2) 生成 numeric,因?yàn)闆]有integer = numeric操作符,只有numeric = numeric。

9.18.4. GREATESTLEAST

GREATEST(value [, ...])
LEAST(value [, ...])

GREATESTLEAST函數(shù)從一個(gè)任意的數(shù)字表達(dá)式列表里選取最大或者最小的數(shù)值。 這些表達(dá)式必須都可以轉(zhuǎn)換成一個(gè)普通的數(shù)據(jù)類型,它將會是結(jié)果類型 (參閱第 10.5 節(jié)獲取細(xì)節(jié))。列表中的 NULL 數(shù)值將被忽略。只有所有表達(dá)式的結(jié)果都是 NULL 的時(shí)候,結(jié)果才會是 NULL。

請注意GREATESTLEAST都不是 SQL 標(biāo)準(zhǔn),但卻是很常見的擴(kuò)展。某些其他數(shù)據(jù)庫讓它們在任何參數(shù)為 NULL 時(shí)返回 NULL,而不是在所有參數(shù)都為 NULL 時(shí)才返回 NULL。


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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號