首先說明mysql 8.0 以前不支持,oracle hive 支持
先說說分組, sql 里面 使用 group by 分組,分組以后會吧分組的 值相等的幾行放到一行。行數變少。
我們先假設 user 表 有用戶的名字,和所屬部門
例子:select name,deptno from user group by deptno
本意按照部門分組,顯示出名字,有的數據庫不支持這種語法,因為按照部分以后同一部門組內的name可能有多個。mysql 可以支持,它顯示的第一個,這個可能和我們要顯示的結果有區別。我們可能想要的第2 個。
在說說聚合函數,分組以后做一些統計的就是聚合函數
例如:select sum(1),deptno from user group by deptno
上面聚合函數分組以后求了部門的人數
我們提出一個問題要求取分組中的第一條 不支持開窗函數的數據庫實現非常麻煩,有興趣的可以百度一下。
百度的寫法很麻煩:但是我試了一下排序以后在查詢就可以
例如:select * from ( select * from test order by test.`status` DESC) t1 group by t1.deptno
結果:
原數據:
支持開窗函數的數據庫寫法:select *from ( select rank() over( partition by xxx order by yyy ) num from t1 ) t2 where t2=1 就可以實現
over 是開窗函數 里面 有 partition by 和 order by , partition by 是指那些數據要放到一個區(和分組類似), order by 指的分區內部排序方式。
備注: partition by 如果沒有 就都算作一個區
備注2:order by 如果缺失name算作 主鍵排序(或者說默認排序)
over 前面 一般會有點別 比如 聚合函數(類似 sum 之類的),分析函數(上面的 rank)
over 后面其實還有點東西 ROWS BETWEEN 表示 前面 函數統計的區間(默認是當前組的第一個到當前組的當前個,也就是不寫等於 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING )
常見分析行數
rank(): 跳躍連續排序 類似 1,2,2,4,4,4
dense_rank() : 連續排序 類似 1,2,2,2,3,3,3,
row_num(): 生成編號 1,2,3,4,5,6
ROWS BETWEEN 后面 分兩個值 ROWS BETWEEN xxx AND yyy
大概可以這么寫
unbounded preceding 起始行
unbounded following 結尾行
current row 當前行
1 preceding 前1行 數字可變
1 following 后1行
總結:普通分組會讓函數減少,over 開窗函數在分組的基礎上不會減少數據,也可以分組統計。
附帶oracle在線測試地址登錄以后可以自己去試試開窗行數:https://livesql.oracle.com/apex/