9.15. 聚集函數

聚集函數 從一套輸入值裡計算一個結果. Table 9-43 顯示了內建聚集函數。 聚集函數的特殊語法在 Section 4.2.7裡解釋.請參考 Part I 獲取附加的介紹性信息.

Table 9-43. 聚集函數

函數參數類型返回類型描述
avg(expression) 所有輸入值的均值(算術平均) smallint, integer, bigint, real, double precision, numeric, 或 interval. 對于任何整數類型輸入,結果都是 numeric 類型. 對于任何浮點輸入,結果都是 double precision 類型. 否則和輸入數據類型相同. 所有輸入值的平均(算術平均)。
count(*) bigint輸入值的數量
count(expression)任意bigint 計算那些 expression 非 NULL 的輸入的個數.
maxX(expression)任何數值,字串或者日期/時間類型與參數同類型所有輸入值中, expression 的最大值
min(expression)任何數值,字串或者日期/時間類型與參數同類型所有輸入值中, expression 的最小值
stddev(expression) smallint, integer, bigint, real, double precision, 或 numeric. 浮點數參數時是double precision, 否則 numeric輸入值的標準採樣偏差(sample standard deviation)
sum(expression) smallint, integer, bigint, real, double precision, numeric, 或者 interval smallintinteger輸入 輸出類型為 bigint.對于bigint輸入輸出類型為 numeric, 浮點數輸入的結果是 double precision. 否則和輸入數據類型相同. 所有輸入值的 expression 的總和
variance(expression) smallint, integer, bigint, real, double precision, 或者 numeric. 浮點數參數是 double precision, 否則是 numeric輸出值的採樣方差(標準採樣偏差的平方).

請注意除了 count 以外, 這些函數在沒有選中行時返回 NULL. 尤其要指出的是對零輸入行進行 sum 將返回 NULL, 而不是我們預期的零. 必要時可以用 coalesce 把 NULL 替換成零.

注意: 習慣了使用其它 RDBMS 產品的用戶可能會對 PostgreSQL 裡面的一些聚集函數的性能特點感到奇怪,特別是對整個表進行聚集的時候 (換句話說,不聲明 WHERE 子句的時候)。 比如,一個下面這樣的查詢:

SELECT min(col) from sometable;

將會被 PostgreSQL 以對整個表進行 順序掃描的形式進行執行。而其它數據庫系統可能會把這樣的查詢 優化成使用某個字段上的索引的方式(如果有索引的話)。 在 PostgreSQL 裡 類似的還有,如果對整個表進行處理的話,聚集函數 max()count() 總是要求一次順序掃描。

PostgreSQL 無法很容易地實現這樣的 優化,因為它還允許用戶定義的聚集查詢。因為 min()max(),和 count() 都是使用一個聚集函數的普通 API 定義的,因此在某些場合裡, 這些函數的執行並不需要規定"特殊轉換"

幸運的是,對于 min()max(), 我們有些簡單的方法來繞開。比如下面顯示的查詢就等效于上面的查詢, 但是,如果在目標字段上有索引,那麼它可以利用一個 B+ 樹索引來優化。

SELECT col from sometable ORDER BY col ASC LIMIT 1;

類似的查詢(通過把上面查詢的 ASC 替換成 DESC 就行了)也可以用在 max() 的地方。

糟糕的是,在對全表操作的時候,沒有類似簡單的查詢可以用于改進 count() 的性能。