?
This document uses PHP Chinese website manual Release
和大多數(shù)其它關(guān)系數(shù)據(jù)庫(kù)產(chǎn)品一樣,
PostgreSQL支持聚集函數(shù)。
一個(gè)聚集函數(shù)從多個(gè)輸入行中計(jì)算出一個(gè)結(jié)果。
比如,我們有在一個(gè)行集合上計(jì)算count
,sum
,
avg
,max
和
min
的函數(shù)。
比如,我們可以用下面的語(yǔ)句找出所有低溫中的最高溫度:
SELECT max(temp_lo) FROM weather;
max ----- 46 (1 row)
如果我們想知道該讀數(shù)發(fā)生在哪個(gè)城市,可能會(huì)用:
SELECT city FROM weather WHERE temp_lo = max(temp_lo); WRONG
不過(guò)這個(gè)方法不能運(yùn)轉(zhuǎn),
因?yàn)榫奂瘮?shù)max
不能用于WHERE子句中。
存在這個(gè)限制是因?yàn)?tt class="LITERAL">WHERE子句決定哪些行可以進(jìn)入聚集階段;
因此它必需在聚集函數(shù)之前計(jì)算。
不過(guò),我們可以用其它方法實(shí)現(xiàn)這個(gè)目的;
這里我們使用subquery:
SELECT city FROM weather WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
city --------------- San Francisco (1 row)
這樣做是可以的,因?yàn)樽硬樵兪且淮为?dú)立的計(jì)算,它獨(dú)立于外層查詢計(jì)算自己的聚集。
聚集同樣也常用于GROUP BY子句。比如,我們可以獲取每個(gè)城市低溫的最高值:
SELECT city, max(temp_lo) FROM weather GROUP BY city;
city | max ---------------+----- Hayward | 37 San Francisco | 46 (2 rows)
這樣每個(gè)城市一個(gè)輸出。每個(gè)聚集結(jié)果都是在匹配該城市的行上面計(jì)算的。 我們可以用HAVING過(guò)濾這些分組:
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"開(kāi)頭的城市,我們可以用:
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在分組和聚集計(jì)算之前選取輸入行(它控制哪些行進(jìn)入聚集計(jì)算), 而HAVING在分組和聚集之后選取輸出行。 因此,WHERE子句不能包含聚集函數(shù); 因?yàn)樵噲D用聚集函數(shù)判斷那些行將要輸入給聚集運(yùn)算是沒(méi)有意義的。 相反,HAVING子句總是包含聚集函數(shù)。 當(dāng)然,你可以寫(xiě)不使用聚集的HAVING子句,但這樣做沒(méi)什么好處, 因?yàn)橥瑯拥臈l件可以更有效地用于WHERE階段。
在前面的例子里,我們可以在WHERE里應(yīng)用城市名稱限制, 因?yàn)樗恍枰奂?。這樣比在HAVING里增加限制更加高效, 因?yàn)槲覀儽苊饬藶槟切┪赐ㄟ^(guò)WHERE檢查的行進(jìn)行分組和聚集計(jì)算。