PostgreSQL UNION、CASE和相關(guān)結(jié)構(gòu)

2021-08-27 11:41 更新

SQL UNION結(jié)構(gòu)必須使可能不相似的類(lèi)型匹配成為一個(gè)單一的結(jié)果集。該決定算法被獨(dú)立地應(yīng)用到一個(gè)聯(lián)合查詢(xún)的每個(gè)輸出列。INTERSECTEXCEPT采用和UNION相同的方法來(lái)決定不相似的類(lèi)型。其他一些結(jié)構(gòu),包括 CASEARRAY、VALUES,以及 GREATESTLEAST函數(shù),使用相同的算法來(lái)使它們的組成表達(dá)式匹配并選擇一種結(jié)果數(shù)據(jù)類(lèi)型。

UNIONCASE和相關(guān)結(jié)構(gòu)的類(lèi)型決定

  1. 如果所有的輸入為相同類(lèi)型,并且不是unknown,那么就決定是該類(lèi)型。

  2. 如果任何輸入是一種域類(lèi)型,在所有后續(xù)步驟中都把它當(dāng)做 該域的基類(lèi)型。 [11]

  3. 如果所有的輸入為unknown類(lèi)型,則決定為text(字符串分類(lèi)的首選類(lèi)型)類(lèi)型。否則,為了剩余規(guī)則,unknown輸入會(huì)被忽略。

  4. 如果非未知輸入不全是相同的類(lèi)型分類(lèi),則失敗。

  5. 選擇第一個(gè)非未知輸入類(lèi)型作為候選類(lèi)型,然后從左到右考慮其他非未知輸入類(lèi)型。 [12] 如果候選類(lèi)型可以隱式轉(zhuǎn)換為其他類(lèi)型,但反之不行,則選擇其他類(lèi)型作為新的候選類(lèi)型。 然后繼續(xù)考慮剩余的輸入。 如果在此過(guò)程的任何階段選擇了首選類(lèi)型,請(qǐng)停止考慮其他輸入。

  6. 將所有輸入轉(zhuǎn)換為最終候選類(lèi)型。如果沒(méi)有從給定輸入類(lèi)型到候選類(lèi)型的隱式轉(zhuǎn)換,則失敗。

下面是一些例子。

例 10.10. 聯(lián)合中未指定類(lèi)型的類(lèi)型決定

SELECT text 'a' AS "text" UNION SELECT 'b';

 text
------
 a
 b
(2 rows)

這里,未知類(lèi)型文字'b'將被決定為類(lèi)型text。


例 10.11. 簡(jiǎn)單聯(lián)合中的類(lèi)型決定

SELECT 1.2 AS "numeric" UNION SELECT 1;

 numeric
---------
       1
     1.2
(2 rows)

文字1.2numeric類(lèi)型,且integer1可以被隱式地造型為numeric,因此使用numeric類(lèi)型。


例 10.12. 可換位聯(lián)合中的類(lèi)型決定

SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL);

 real
------
    1
  2.2
(2 rows)

這里,由于類(lèi)型real被能被隱式地造型為integer,而integer可以被隱式地造型為real,聯(lián)合結(jié)果類(lèi)型被決定為real。


例 10.13. 嵌套合并中的類(lèi)型決定

SELECT NULL UNION SELECT NULL UNION SELECT 1;

ERROR:  UNION types text and integer cannot be matched

這個(gè)失敗發(fā)生的原因是PostgreSQL把多個(gè)UNION當(dāng)作是成對(duì)操作的嵌套,也就是說(shuō)上面的輸入等同于:

(SELECT NULL UNION SELECT NULL) UNION SELECT 1;

根據(jù)上面給定的規(guī)則,內(nèi)層的UNION被確定為類(lèi)型text。然后外層的UNION的輸入是類(lèi)型textinteger,這就導(dǎo)致了上面看到的錯(cuò)誤。通過(guò)確保最左邊的UNION至少有一個(gè)輸入類(lèi)型為想要的結(jié)果類(lèi)型,就可以修正這個(gè)問(wèn)題。

INTERSECTEXCEPT操作也被當(dāng)作成對(duì)操作。不過(guò),這一節(jié)中描述的其他結(jié)構(gòu)會(huì)在一個(gè)決定步驟中考慮所有的輸入。




[11] 多少有些類(lèi)似于對(duì)待用于操作符和函數(shù)的域輸入的方式,這種行為允許 一種域類(lèi)型能通過(guò)一個(gè)UNION或相似的結(jié)構(gòu)保留下來(lái), 只要用戶(hù)小心地確保所有的輸入都是(顯式地或隱式地)準(zhǔn)確類(lèi)型。否 則會(huì)使用該域的基類(lèi)型。

[12] 出于歷史原因,CASE將其ELSE子句(如果有的話)視為第一個(gè)輸入,之后再考慮THEN子句。在所有其他情況下, 從左到右表示表達(dá)式在查詢(xún)文本中出現(xiàn)的順序。


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

掃描二維碼

下載編程獅App

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

編程獅公眾號(hào)