SQL必學必會之窗口函數
在SQL中,窗口函數是一種強大的工具,用于在查詢結果中執行聚合、排序和分組操作,而不影響原始表的行數。這篇文章將介紹窗口函數的基本概念以及如何使用它們來解決各種數據分析和報告需求。

1.窗口函數基礎
窗口函數的基本語法如下:
<窗口函數> over (partition by <用于分組的列名> order by <用于排序的列名>)其中,partition by用于對表進行分組,而不會減少原表的行數。例如,按班級分組可以使用 partition by 班級。
order by則用于對分組后的結果進行排序,可以選擇升序(asc)或降序(desc)。例如,order by 成績 desc 表示按成績降序排列。
窗口函數的優勢在于它們能夠同時實現分組和排序的功能,而不像 group by 子句那樣減少表的行數。這意味著你可以在不失去原始數據的情況下執行聚合和排名操作。
2.窗口函數示例
示例:統計每個班級的人數
讓我們看一個示例,假設我們要統計每個班級的學生人數。使用窗口函數,我們可以輕松實現這一目標:
SELECT *,
COUNT(*) OVER (PARTITION BY 班級) AS 班級人數
FROM 學生表在這個示例中,COUNT(*) 函數作為窗口函數,使用 PARTITION BY 班級 實現了按班級分組并計算每個班級的學生人數,同時原始表的行數依舊不變,而每行數據則增加了一列新列`班級人數`。
3.窗口函數的三種排序方式
窗口函數有多種類型,包括 rank()、dense_rank() 和 row_number()。它們在處理并列名次時的行為不同:
rank()
函數會占用下一名次的位置,如果有并列名次的行。例如,如果前3名是并列的名次,結果將是 1,1,1,4。
dense_rank()
函數不會占用下一名次的位置,如果有并列名次的行。例如,前3名是并列的名次,結果是 1,1,1,2。
row_number()
函數不考慮并列名次,排名是正常的。例如,前3名是并列的名次,排名是正常的 1,2,3,4。
窗口函數還可以與聚合函數一起使用,以在結果中執行聚合操作,如總和、平均、計數、最大和最小值。以下是示例:
SELECT *,
SUM(成績) OVER (ORDER BY 學號) AS 當前總分,
AVG(成績) OVER (ORDER BY 學號) AS 當前平均分,
COUNT(成績) OVER (ORDER BY 學號) AS 當前人數,
MAX(成績) OVER (ORDER BY 學號) AS 最高分,
MIN(成績) OVER (ORDER BY 學號) AS 最低分
FROM 班級表在此示例中,我們使用窗口函數將聚合函數應用于成績,并按學號排序,以計算每個學生的當前總分、平均分、人數、最高分和最低分。
4.結論
窗口函數是 SQL 查詢中強大的工具,它們允許我們在不減少原始數據行數的情況下執行分組、排序和聚合操作。通過了解窗口函數的基本語法和應用,您可以更靈活地分析數據和生成報告。無論是數據分析師還是數據庫開發人員,掌握窗口函數都是一個有用的技能,可以大大簡化復雜查詢的編寫和理解。























