?
本文檔使用 php中文網(wǎng)手冊(cè) 發(fā)布
CREATE AGGREGATE name ( input_data_type [ , ... ] ) (
SFUNC = sfunc,
STYPE = state_data_type
[ , FINALFUNC = ffunc ]
[ , INITCOND = initial_condition ]
[ , SORTOP = sort_operator ]
)
或者舊語(yǔ)法
CREATE AGGREGATE name (
BASETYPE = base_type,
SFUNC = sfunc,
STYPE = state_data_type
[ , FINALFUNC = ffunc ]
[ , INITCOND = initial_condition ]
[ , SORTOP = sort_operator ]
)
CREATE AGGREGATE定義一個(gè)新的聚集函數(shù)。一些常用的聚集函數(shù)已經(jīng)包含在 基礎(chǔ)軟件包里了;在節(jié)Section 9.18里有文檔記錄。如果你需要定義 一個(gè)新類型或需要一個(gè)還沒(méi)有提供的聚集函數(shù),這時(shí)CREATE AGGREGATE便可 排上用場(chǎng)。
如果給出了一個(gè)模式的名字(比如CREATE AGGREGATE myschema.myagg ...),那么該 聚集函數(shù)是在指定模式中創(chuàng)建的。否則它是在當(dāng)前模式中創(chuàng)建的。
一個(gè)聚集函數(shù)是用它的名字和輸入數(shù)據(jù)類型來(lái)標(biāo)識(shí)的。同一模式中如果兩個(gè)聚集處理的輸入數(shù)據(jù)不同, 它們可以有相同的名字。一個(gè)聚集函數(shù)的輸入數(shù)據(jù)類型必須和所有同一模式中的普通函數(shù)的名字和輸入 類型不同。
一個(gè)聚集函數(shù)是用一個(gè)或兩個(gè)普通函數(shù)做成的:一個(gè)狀態(tài)轉(zhuǎn)換函數(shù) sfunc和一個(gè)可選的最終計(jì)算函數(shù) ffunc。它們是這樣使用的:
sfunc( internal-state, next-data-values ) ---> next-internal-state ffunc( internal-state ) ---> aggregate-value
PostgreSQL創(chuàng)建一個(gè)類型為 stype的臨時(shí)變量。它保存這個(gè)聚集的 當(dāng)前內(nèi)部狀態(tài)。對(duì)于每個(gè)輸入數(shù)據(jù)條目,都調(diào)用狀態(tài)轉(zhuǎn)換函數(shù)計(jì)算內(nèi)部狀態(tài)值的新數(shù)值。 在處理完所有數(shù)據(jù)后,調(diào)用一次最終處理函數(shù)以計(jì)算聚集的返回值。如果沒(méi)有最終處理函數(shù), 則將最后的狀態(tài)值當(dāng)做返回值。
一個(gè)聚集函數(shù)還可能提供一個(gè)初始條件,也就是內(nèi)部狀態(tài)值的初始值。這個(gè)值是作為一個(gè)類型 為text的字段存儲(chǔ)在數(shù)據(jù)庫(kù)里的,不過(guò)它們必須是狀態(tài)值數(shù)據(jù)類型的合法的外部 表現(xiàn)形式的常量。如果沒(méi)有提供狀態(tài),那么狀態(tài)值初始化為 NULL 。
如果該狀態(tài)轉(zhuǎn)換函數(shù)被定義為"strict",那么就不能用 NULL 輸入調(diào)用它。此時(shí),
聚集的執(zhí)行如下所述。帶有任何 NULL 輸入值的行將被忽略(不調(diào)用此函數(shù)并且保留前一個(gè)狀態(tài)值)。
如果初始狀態(tài)值是 NULL ,那么在第一個(gè)含有非 NULL 值的行上,使用第一個(gè)參數(shù)值替換狀態(tài)值,
然后狀態(tài)轉(zhuǎn)換函數(shù)在隨后所有的含有非 NULL 值的行上調(diào)用。這樣做讓比較容易實(shí)現(xiàn)像
max
這樣的聚集。請(qǐng)注意這種行為只是當(dāng)
state_data_type與
input_data_type相同的時(shí)候才表現(xiàn)出來(lái)。
如果這些類型不同,你必須提供一個(gè)非 NULL 的初始條件或者使用一個(gè)非"strice"的狀態(tài)轉(zhuǎn)換函數(shù)。
如果狀態(tài)轉(zhuǎn)換函數(shù)不是嚴(yán)格(strict)的,那么它將無(wú)條件地在每個(gè)輸入行上調(diào)用,并且必須自行 處理 NULL 輸入和 NULL 轉(zhuǎn)換值,這樣就允許聚集的作者對(duì)聚集中的 NULL 有完全的控制。
如果最終轉(zhuǎn)換函數(shù)定義為"strict",那么如果最終狀態(tài)值是 NULL 時(shí)就不會(huì)調(diào)用它;
而是自動(dòng)輸出一個(gè) NULL 結(jié)果。這才是 strict 函數(shù)的正常特征。不管是那種情況,最終處理函數(shù)
可以自由選擇是否返回 NULL 。比如,avg
的最終處理函數(shù)在零輸入記錄時(shí)
就會(huì)返回 NULL 。
行為類似MIN
或MAX
的聚集有時(shí)候可以優(yōu)化為使用索引,而不用掃描
每個(gè)輸入行。如果這個(gè)聚集可以如此優(yōu)化,則用一個(gè)排序操作符標(biāo)識(shí)它。這里基本的要求是聚集
必須以操作符歸納出來(lái)的排序順序生成第一個(gè)元素;換句話說(shuō)
SELECT agg(col) FROM tab;
必須等于:
SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
更多的假設(shè)是聚集忽略 NULL 輸入,并且只有在輸入沒(méi)有非空數(shù)值的時(shí)候,它才生成NULL結(jié)果。
通常,數(shù)據(jù)類型的 < 操作符是MIN
的適用排序操作符,而 > 是MAX
的適用操作符。請(qǐng)注意,除非聲明的操作符是 B-tree 索引操作符類的"小于"或者"大于"策略號(hào),
否則這種優(yōu)化將不會(huì)生效。
要?jiǎng)?chuàng)建的聚集函數(shù)名(可以有模式修飾)
該聚集函數(shù)要處理的輸入數(shù)據(jù)類型。要?jiǎng)?chuàng)建一個(gè)零參數(shù)聚集函數(shù),可以使用 * 代替輸入數(shù)據(jù)類型 列表。count(*) 就是這種聚集函數(shù)的一個(gè)實(shí)例。
在舊式的CREATE AGGREGATE語(yǔ)法中,輸入數(shù)據(jù)類型是通過(guò)basetype 參數(shù)指定的,而不是寫在聚集的名稱之后。需要注意的是這種舊式語(yǔ)法僅允許一個(gè)輸入?yún)?shù)。 要?jiǎng)?chuàng)建一個(gè)零參數(shù)聚集函數(shù),可以將 basetype 指定為"ANY"(而不是*)。
將在每一個(gè)輸入行上調(diào)用的狀態(tài)轉(zhuǎn)換函數(shù)的名稱。對(duì)于有 N 個(gè)參數(shù)的聚集函數(shù), sfunc必須有 N+1 個(gè)參數(shù),其中的第一個(gè)參數(shù)類型為 state_data_type,其余的匹配已聲明的 輸入數(shù)據(jù)類型。函數(shù)必須返回一個(gè)state_data_type 類型的值。這個(gè)函數(shù)接受當(dāng)前狀態(tài)值和當(dāng)前輸入數(shù)據(jù),并返回下個(gè)狀態(tài)值。
聚集的狀態(tài)值的數(shù)據(jù)類型
在轉(zhuǎn)換完所有輸入行后調(diào)用的最終處理函數(shù),它計(jì)算聚集的結(jié)果。此函數(shù)必須接受一個(gè)類型為 state_data_type的參數(shù)。聚集的輸出數(shù)據(jù) 類型被定義為此函數(shù)的返回類型。如果沒(méi)有聲明 ffunc則使用聚集結(jié)果的狀態(tài)值作為聚集的結(jié)果, 且輸出類型為state_data_type。
狀態(tài)值的初始設(shè)置(值)。它必須是一個(gè) state_data_type類型可以接受的文本常量值。 如果沒(méi)有聲明,狀態(tài)值初始為 NULL 。
用于MIN
或MAX
類型聚集的排序操作符。這個(gè)只是一個(gè)操作符名
(可以有模式修飾)。這個(gè)操作符假設(shè)接受和聚集一樣的輸入數(shù)據(jù)類型。
CREATE AGGREGATE的參數(shù)可以以任何順序書(shū)寫,而不只是上面顯示的順序。
See Section 35.10.
CREATE AGGREGATE是PostgreSQL語(yǔ)言的擴(kuò)展。SQL標(biāo)準(zhǔn)沒(méi)有提供用戶自定義聚集函數(shù)的功能。