| PostgreSQL 7.4 文檔 | ||||
|---|---|---|---|---|
| Prev | Fast Backward | Chapter 2. SQL 語言 | Fast Forward | Next |
和大多數其它關系數據庫產品一樣, PostgreSQL 支持聚集函數。 一個聚集函數從多個輸入行中計算出一個結果。 比如,我們有在一個行集合上計算 count(數目), sum(和),avg(均值), max(最大值)和min(最小值)的函數。
比如,我們可以用下面的語句找出所有記錄中低溫中的最高溫度
SELECT max(temp_lo) FROM weather;
max ----- 46 (1 row)
SELECT city FROM weather WHERE temp_lo = max(temp_lo); WRONG
不過這個方法不能運轉,因為聚集 max 不能用于 WHERE 子句中。 (存在這個限制是因為 WHERE 子句決定哪些行可以進入聚集階段;因此它必需在聚集函數之前計算。) 不過,我們通常都可以用其它方法實現我們的目的;這裡我們就可以使用子查詢:
SELECT city FROM weather
WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
city --------------- San Francisco (1 row)
這樣做是 OK 的,因為子查詢是一次獨立的計算,它獨立于外層的查詢計算出自己的聚集。
聚集同樣也常用于 GROUP BY 子句。比如, 我們可以獲取每個城市低溫的最高值
SELECT city, max(temp_lo)
FROM weather
GROUP BY city;
city | max ---------------+----- Hayward | 37 San Francisco | 46 (2 rows)
這樣給我們每個城市一個輸出。 每個聚集結果都是在匹配該城市的行上面計算的。 我們可以用 HAVING 過濾這些分組:
SELECT city, max(temp_lo)
FROM weather
GROUP BY city
HAVING max(temp_lo) < 40;
city | max ---------+----- Hayward | 37 (1 row)
這樣就只給出那些 temp_lo 數值曾經有低于 40 度溫度的城市。 最後,如果我們只關心那些名字以 "S" 開頭的城市,我們可以用
SELECT city, max(temp_lo)
FROM weather
WHERE city LIKE 'S%'(1)
GROUP BY city
HAVING max(temp_lo) < 40;
理解聚集和SQL的 WHERE 以及 HAVING 子句之間的關系對我們非常重要。 WHERE 和 HAVING 的基本區別如下: WHERE 在分組和聚集計算之前選取輸入行(因此,它控制哪些行進入聚集計算), 而 HAVING 在分組和聚集之後選取分組的行。 因此,WHERE 子句不能包含聚集函數; 因為試圖用聚集函數判斷那些行輸入給聚集運算是沒有意義的。 相反,HAVING 子句總是包含聚集函數。 (嚴格說來,你可以寫不使用聚集的 HAVING 子句, 但這樣做只是白費勁;同樣的條件可以更有效地用于 WHERE 階段。)
通過觀察我們可以發現,我們可以在 WHERE 裡應用城市名稱限制,因為它不需要聚集。 這樣比在 HAVING 裡增加限制更加高效,因為我們避免了為那些未通過 WHERE 檢查的行進行分組和聚集計算。