首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 教學

Oracle 分析函數完整指南:語法、窗口子句、排名、報表與行列轉換實戰

     編輯:Oracle 教學

分析函數核心語法

子句功能關鍵點
PARTITION BY分組,函數在各分區獨立計算省略 = 整張表為單一分區
ORDER BY分區內排序,決定窗口順序排名函數必須;聚合函數影響窗口範圍
WINDOWING定義窗口範圍 (RANGE/ROWS)預設: RANGE UNBOUNDED PRECEDING TO CURRENT ROW


窗口子句詳細解析

RANGE — 邏輯偏移 (依 ORDER BY 值)

-- 當前行及前 2 行
SUM(sal) OVER (PARTITION BY deptno ORDER BY sal ROWS 2 PRECEDING)

-- 整個分區所有行
SUM(sal) OVER (PARTITION BY deptno ORDER BY sal ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)

關鍵差異:RANGE vs ROWS

特性RANGEROWS
基準ORDER BY 欄位值物理行位置
相同值處理同值視為同一群組各行獨立計算
效能較慢 (需排序分組)較快
適用數值/日期累加、移動平均Top-N、固定行數窗口

核心分析函數分類與範例

1. 聚合類

SELECT 
  empno, ename, sal, deptno,
  COUNT(*) OVER (PARTITION BY deptno) dept_cnt,
  ROUND(AVG(sal) OVER (PARTITION BY deptno), 2) dept_avg,
  MAX(sal) OVER (PARTITION BY deptno) dept_max,
  MIN(sal) OVER (PARTITION BY deptno) dept_min,
  SUM(sal) OVER (PARTITION BY deptno) dept_sum
FROM emp;

2. 排名類

函數行為重複值處理
RANK()標準排名跳號 (1,2,2,4)
DENSE_RANK()密集排名不跳號 (1,2,2,3)
ROW_NUMBER()唯一行號強制唯一 (1,2,3,4)
-- 首/尾值 (需指定完整窗口)
FIRST_VALUE(sal) OVER (PARTITION BY deptno ORDER BY sal 
  RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) first_sal,
LAST_VALUE(sal) OVER (PARTITION BY deptno ORDER BY sal 
  RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) last_sal

-- 相鄰行存取
LAG(sal, 2, 0) OVER (PARTITION BY deptno ORDER BY sal) lag_2,  -- 前 2 行
LEAD(sal, 2, 0) OVER (PARTITION BY deptno ORDER BY sal) lead_2  -- 後 2 行

4. KEEP 子句 (首/尾值聚合)

函數功能範例
CUME_DIST()累積分布 (0~1)排名/總行數
NTILE(n)分桶 (1~n)NTILE(4) 四分位數
RATIO_TO_REPORT()值佔總和比例薪資佔部門總薪資%
PERCENT_RANK()百分位排名(RANK-1)/(總數-1)


SELECT * FROM (
  SELECT deptno, job, sal FROM emp
)
PIVOT (
  SUM(sal) FOR job IN (
    'CLERK' AS clerk_sal,
    'MANAGER' AS mgr_sal,
    'ANALYST' AS analyst_sal,
    'SALESMAN' AS sales_sal,
    'PRESIDENT' AS pres_sal
  )
)
ORDER BY deptno;

多重彙總 PIVOT

SELECT * FROM (
  SELECT deptno, job, sal FROM emp
)
PIVOT XML (
  SUM(sal) FOR job IN (ANY)
)
ORDER BY deptno;

UNPIVOT — 列轉行 (逆向)

SELECT deptno,
  SUM(DECODE(job, 'CLERK', sal)) clerk_sal,
  SUM(DECODE(job, 'MANAGER', sal)) mgr_sal,
  SUM(DECODE(job, 'ANALYST', sal)) analyst_sal,
  SUM(DECODE(job, 'SALESMAN', sal)) sales_sal,
  SUM(DECODE(job, 'PRESIDENT', sal)) pres_sal
FROM emp
GROUP BY deptno;

效能與最佳實踐

  1. 單次掃描多重統計:分析函數避免多次自我聯結/子查詢。
  2. 索引支援:PARTITION BY + ORDER BY 欄位建立複合索引可避免排序。
  3. 窗口預設值陷阱:有 ORDER BY 時預設窗口為 RANGE UNBOUNDED PRECEDING TO CURRENT ROW (累加),非整個分區。
  4. NULLS FIRST/LAST:明確指定 NULL 排序位置,避免跨版本差異。
  5. 大表分頁:ROW_NUMBER() OVER (ORDER BY ...) RN + WHERE RN BETWEEN :start AND :end。

總結

分析函數是 SQL 進階分析的「瑞士刀」:單次掃描、多維度計算、靈活窗口控制。掌握 PARTITION BY、ORDER BY、RANGE/ROWS 三大子句互動,熟練運用排名、聚合、取值、報表四大類函數,並善用 PIVOT/UNPIVOT 完成行列轉換,能以極簡潔 SQL 解決複雜報表與分析需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved