連接條件使用 非等號比較運算符:>、<、>=、<=、BETWEEN ... AND ...、!= 等。典型場景:數值範圍匹配、區間歸類。
-- SALGRADE 結構
-- GRADE | LOSAL | HISAL
-- 1 | 700 | 1200
-- 2 | 1201 | 1400
-- ...
-- 查詢員工編號、姓名、薪資、薪資等級
SELECT e.empno, e.ename, e.sal, s.grade
FROM emp e
JOIN salgrade s ON e.sal BETWEEN s.losal AND s.hisal;
BETWEEN ... AND 包含邊界值。SELECT e.empno, e.ename, e.sal, s.grade, d.dname
FROM emp e
JOIN dept d ON e.deptno = d.deptno -- 等值連接
JOIN salgrade s ON e.sal BETWEEN s.losal AND s.hisal; -- 非等值連接
表與自身連接,通過表別名區分不同角色。本質是將同一表視為兩個邏輯表,常用於層級結構(員工-經理、分類樹、BOM 物料清單)。
SELECT w.ename AS worker, w.mgr AS mgr_empno, m.ename AS manager
FROM emp w
JOIN emp m ON w.mgr = m.empno;
w(Worker):員工角色,mgr 存儲經理的 empno。m(Manager):經理角色,通過 empno 匹配。mgr IS NULL)不會顯示(內連接特性)。SELECT w.ename AS worker, m.ename AS manager
FROM emp w
LEFT JOIN emp m ON w.mgr = m.empno;
-- 從 KING 開始,顯示完整管理鏈
SELECT LPAD(' ', 2*(LEVEL-1)) || ename AS org_chart
FROM emp
START WITH mgr IS NULL
CONNECT BY PRIOR empno = mgr;
輸出縮進層級結構圖。11g+ 推薦 ANSI WITH RECURSIVE(CTE)跨平台遞歸。
-- 查詢:員工姓名、部門名、薪資等級、經理姓名
SELECT e.ename AS emp_name,
d.dname AS dept_name,
s.grade AS sal_grade,
m.ename AS mgr_name
FROM emp e
JOIN dept d ON e.deptno = d.deptno -- 等值
JOIN salgrade s ON e.sal BETWEEN s.losal AND s.hisal -- 非等值
LEFT JOIN emp m ON e.mgr = m.empno; -- 自連接(外連接保留無經理)
| 場景 | 建議 |
|---|---|
| 非等值連接大表 | 極易產生笛卡爾積級別行數爆炸,務必先過濾驅動表、確保統計信息準確、考慮物化視圖預聚合 |
| 自連接深層遞歸 | CONNECT BY 深度超過 1000 可能報錯,改用 WITH RECURSIVE 或應用層遞歸 |
| 混合連接順序 | 優化器自動重排,但可用 /*+ LEADING(e d s m) */ 固定驅動順序 |
| 可讀性 | 統一使用 ANSI JOIN,別名語義化(w/m, e/d/s),條件分行對齊 |
非等值連接解決「範圍歸類」,自連接解決「層級關係」。兩者結合 ANSI JOIN 標準語法,配合 BETWEEN、LEFT JOIN、CONNECT BY/WITH RECURSIVE,即可優雅表達複雜業務邏輯。關鍵在於:理解數據分佈、預估結果集大小、選擇正確連接類型、驗證執行計劃。