來源:中國統計網
DROP TABLE IF EXISTS Marks;CREATE TABLE Marks(學生 VARCHAR(10),
科目 CHAR(2),
分數 INT);
insert into Marks values
('趙四','語文',88),('趙四','數學',48),('趙四','英語',75),
('張三','語文',30),('張三','數學',75),('張三','英語',75),
('王五','語文',90),('王五','數學',94),('王五','英語',70),
('李四','語文',82),('李四','數學',69),('李四','英語',90);
SELECT * FROM Marks;
-- 作爲窗口函數
SELECT 學生,科目,分數,
SUM(分數) OVER (PARTITION BY 學生) AS '總分'
FROM Marks;
-- 與直接使用sum()聚合函數得到的結果一樣
SELECT 學生,SUM(分數) AS '總分'
FROM Marks
GROUP BY 學生;
窗口函數的語法
window_function_name(expression)
OVER (
[partition_defintion]
[order_definition]
[frame_definition]
)
PARTITION BY expr [, expr] ...
ORDER BY expr [ASC|DESC] [, expr [ASC|DESC]] ...
SELECT 學生,科目,分數,
MAX(分數) OVER (PARTITION BY 學生 ORDER BY 分數 DESC) AS '最高分'
FROM Marks;
frame_clause:
frame_units frame_extentframe_units:
| RANGE}frame_extent:
| frame_between}frame_between:
BETWEEN frame_start AND frame_endframe_start, frame_end: {
CURRENT ROW
UNBOUNDED PRECEDING
UNBOUNDED FOLLOWING
expr PRECEDING
expr FOLLOWING}
SELECT 學生,科目,分數,
AVG(分數) OVER (PARTITION BY 學生
ORDER BY 分數 ASC
ROWS 2 preceding) AS moving_avg
FROM Marks;
SELECT 學生,科目,分數,
AVG(分數) OVER (PARTITION BY 學生
ORDER BY 分數 ASC
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS AVGFROM Marks;
CURRENT ROW: 當前行
UNBOUNDED PRECEDING: 區間的第一行
UNBOUNDED FOLLOWING:區間的最後一行
N PRECEDING: 當前行之前的N行,可以是數字,也可以是一個能計算出數字的表達式
N FOLLOWING:當前行之後的N行,可以是數字,也可以是一個能計算出數字的表達式
如果有ORDER BY,SQL會默認幀是區間內從第一行(UNBOUNDED PRECEDING)到當前行(CURRENTROW)
SELECT 學生,科目,分數,
MAX(分數) OVER (PARTITION BY 學生
ORDER BY 分數 ASC) AS '最高分' FROM Marks;-- 結果相同SELECT 學生,科目,分數,
MAX(分數) OVER (PARTITION BY 學生
ORDER BY 分數 ASC
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS '最高分' FROM Marks;
如果沒有ORDER BY,SQL會默認幀是區間內從第一行(UNBOUNDED PRECEDING)到最後一行(UNBOUNDED FOLLOWING)
SELECT 學生,科目,分數,
MAX(分數) OVER (PARTITION BY 學生) AS '最高分'
FROM Marks;
-- 結果相同
SELECT 學生,科目,分數,
MAX(分數) OVER (PARTITION BY 學生
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS '最高分'
FROM Marks;
ROW_NUMBER: 函數名即是排序方法,也就是輸出結果集分區的行號(例如:1,2,3,4,5...)
RANK: 返回結果集的分區內數據進行跳躍排序。也就是爲相同數值的行輸出相同排序結果,對於下一行不同的數據將返回行號(例如:1,1,3,4...)
DENSE_RANK: 返回結果集分區中每行的連續排名,排名值沒有間斷。行排名等於該行之前不同排名值的數量加一(例如:1,1,2,3,4...)
NTILE: 將有序分區中的數據分發到指定數目的組中。以本文數據爲例,將60-90分的分數等分爲4組,即第1組爲[90, 82.5),第2組爲[82.5, 75),第3組爲[75, 67.5),第4組爲[67.5, 60]
SELECT 學生,科目,分數
,ROW_NUMBER() OVER (PARTITION BY 科目 ORDER BY 分數 DESC) AS "Row_Number"
,RANK() OVER (PARTITION BY 科目 ORDER BY 分數 DESC) AS 'Rank'
,DENSE_RANK() OVER (PARTITION BY 科目 ORDER BY 分數 DESC) AS "Dense_Rank"
,NTILE(4) OVER (PARTITION BY 科目 ORDER BY 分數 DESC) AS 'Quartile'
FROM Marks;
後臺回覆暗號「進羣」,即刻加入讀者交流羣~
本文分享自微信公衆號 - 凹凸數據(alltodata)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。