group by 函數主要用來對數據進行分組,over()函數則是一個“開窗函數”,它更多的是與聚合函數如:sum()、max()、min()、avg()、count()等函數以及排名函數如:row_number()、rank()、dense_rank()、ntile()函數結合使用。
1.group by 函數
原始數據如下,數據表名為hr.employeee
對以上數據按照city字段進行分組,並計算了每組中存在的行數:
select city,count(city)as n from hr.employeee group by city;
分組結果:
根據以上結果,London這個值在原始數據中出現了4次,該組的行數為4。
2.over()函數
一般來說,當使用了group by 進行分組查詢,select查詢階段出現的columnlists如果沒有出現在group by 后作為分組依據,就必須被包含在聚合函數中。但是往往在書寫的時候就會忘記這個限制。over()函數則很好的解決了這個問題,該函數能夠實現分組的效果。
原始數據如下(總共有830行):
進行以下查詢:
select distinct val,row_number()over(order by val)as rownum from sales.ordervalues
運行結果仍然是830行,但實際該數據是存在5行的重復數據,所以說,明明在select階段使用distinct取不同值,為何會沒作用呢???
T-SQL語言基礎這本書是這樣解釋的:row_number函數是在distinct子句之前處理的,當其為數據分配了唯一的行號后,再處理distinct子句,所以這時不會有任何重復的行。 (還未理解透,distinct是對val做處理,只要val存在重復值就剔除呀,難道不是這樣的嗎?--因為distinct是對其后的兩列數據進行去重的!)
這也說明,在同一select子句中不能同時使用distinct和row_number()函數,因為distinct會失效!!!
要想得到不含重復值的數據,可以進行以下查詢:
select val,row_number()over(order by val)as rownum from sales.ordervalues group by val;
這個時候就篩除了5行重復數據。
以下情形值得注意:

--代碼1 --分組之后計算每組的行數 select val,count(val)as n from sales.ordervalues group by val;--注意查看分組后val值,這時已經達到去重的效果了 --代碼2 --利用over函數達到分組效果,partition by對某列字段分區 select val,count(val)over(partition by val )as num from sales.ordervalues --代碼3 --代碼2和3進行對比,注意區別 select val,count(val)over(partition by val )as num from sales.ordervalues group by val;
代碼1:利用group by 子句進行分組查詢,並計算了每組的行數,觀察結果發現,group by起到了去重的功效。
代碼2:利用over函數達到分組效果,partition by對某列字段分區,並計算分區后每組的行數,這種情況下並沒有去重的效果。
代碼3:由於group by 處理順序優於select,前面說到group by具有去重功效,每組數據只有唯一值!因此再進行over函數計算每組行數只有一個結果。
再來一組查詢對比,當在over函數中同時指定partition by 和order by 的字段為同一個時,排序失效:

--按照val降序排列失效!!! select val,count(val)over(partition by val order by val desc )as num from sales.ordervalues; select val,count(val)over(partition by val )as num from sales.ordervalues order by val desc ;
以上按照val降序排列失效的原因在於,partition by 分區后的數據即按照了一定的順序(升序)排列了,再使用order by 排序就會失效(個人理解):

select val from sales.ordervalues select val from sales.ordervalues group by val;
以上對比查詢看到,group by不僅具有去重功效,還有按照升序排列數據的功能(單列數據查詢)。