?
本文檔使用 php中文網(wǎng)手冊 發(fā)布
和大多數(shù)其它關(guān)系數(shù)據(jù)庫產(chǎn)品一樣,
PostgreSQL支持聚集函數(shù)。
一個聚集函數(shù)從多個輸入行中計算出一個結(jié)果。
比如,我們有在一個行集合上計算count
,sum
,
avg
,max
和
min
的函數(shù)。
比如,我們可以用下面的語句找出所有低溫中的最高溫度:
SELECT max(temp_lo) FROM weather;
max ----- 46 (1 row)
如果我們想知道該讀數(shù)發(fā)生在哪個城市,可能會用:
SELECT city FROM weather WHERE temp_lo = max(temp_lo); WRONG
不過這個方法不能運轉(zhuǎn),
因為聚集函數(shù)max
不能用于WHERE子句中。
存在這個限制是因為WHERE子句決定哪些行可以進入聚集階段;
因此它必需在聚集函數(shù)之前計算。
不過,我們可以用其它方法實現(xiàn)這個目的;
這里我們使用subquery:
SELECT city FROM weather WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
city --------------- San Francisco (1 row)
這樣做是可以的,因為子查詢是一次獨立的計算,它獨立于外層查詢計算自己的聚集。
聚集同樣也常用于GROUP BY子句。比如,我們可以獲取每個城市低溫的最高值:
SELECT city, max(temp_lo) FROM weather GROUP BY city;
city | max ---------------+----- Hayward | 37 San Francisco | 46 (2 rows)
這樣每個城市一個輸出。每個聚集結(jié)果都是在匹配該城市的行上面計算的。 我們可以用HAVING過濾這些分組:
SELECT city, max(temp_lo) FROM weather GROUP BY city HAVING max(temp_lo) < 40;
city | max ---------+----- Hayward | 37 (1 row)
這樣就只給出那些temp_lo值曾經(jīng)有低于40度的城市。 最后,如果我們只關(guān)心那些名字以"S"開頭的城市,我們可以用:
SELECT city, max(temp_lo) FROM weather WHERE city LIKE 'S%'(1) GROUP BY city HAVING max(temp_lo) < 40;
理解聚集和SQL的WHERE和HAVING子句之間的關(guān)系非常重要。 WHERE和HAVING的基本區(qū)別如下: WHERE在分組和聚集計算之前選取輸入行(它控制哪些行進入聚集計算), 而HAVING在分組和聚集之后選取輸出行。 因此,WHERE子句不能包含聚集函數(shù); 因為試圖用聚集函數(shù)判斷那些行將要輸入給聚集運算是沒有意義的。 相反,HAVING子句總是包含聚集函數(shù)。 當(dāng)然,你可以寫不使用聚集的HAVING子句,但這樣做沒什么好處, 因為同樣的條件可以更有效地用于WHERE階段。
在前面的例子里,我們可以在WHERE里應(yīng)用城市名稱限制, 因為它不需要聚集。這樣比在HAVING里增加限制更加高效, 因為我們避免了為那些未通過WHERE檢查的行進行分組和聚集計算。