從多個表查詢資料,需在 WHERE 指定連接條件,否則產生笛卡爾積。
SELECT 欄位清單
FROM table1, table2
WHERE table1.col = table2.col;
-- 笛卡爾積:14 x 5 = 70 筆
SELECT empno, ename, sal, emp.deptno, dname, loc FROM emp, dept;
-- 等值連接:14 筆
SELECT empno, ename, sal, emp.deptno, dname, loc
FROM emp, dept
WHERE emp.deptno = dept.deptno;
| 類型 | 說明 |
|---|---|
| 等值連接 | 以等號比對欄位,最常用 |
| 非等值連接 | 使用範圍比對(如 BETWEEN) |
| 自連接 | 表連接自身,需不同別名 |
| 外連接 | 左/右外連接,保留不符合條件的列 |
SELECT empno, ename, emp.deptno, dname
FROM emp, dept
WHERE emp.deptno = dept.deptno;
場景:查詢員工薪資等級(salgrade 表)。
SELECT empno, ename, sal, grade AS 薪資等級
FROM emp, salgrade
WHERE sal BETWEEN losal AND hisal;
-- 左外連接:顯示 emp 所有列,dept 無對應也顯示
SELECT e.empno, e.ename, d.dname
FROM emp e, dept d
WHERE e.deptno = d.deptno(+);
-- 右外連接:顯示 dept 所有列,emp 無對應也顯示
SELECT e.empno, e.ename, d.dname
FROM emp e, dept d
WHERE e.deptno(+) = d.deptno;
查詢員工及其主管資訊。
SELECT a.empno, a.ename, a.mgr, b.ename AS mgr_name
FROM emp a, emp b
WHERE a.mgr = b.empno;
SELECT 欄位清單
FROM table1
[CROSS JOIN table2]
[NATURAL JOIN table2]
[JOIN table2 USING (col_name)]
[JOIN table2 ON (table1.col = table2.col)]
[(LEFT | RIGHT | FULL OUTER) JOIN table2 ON (table1.col = table2.col)]
...;
產生笛卡爾積,等同無 WHERE 連接條件。
SELECT empno, ename, dname FROM emp a CROSS JOIN dept b;
自動基於所有同名欄位等值連接。
SELECT empno, ename, sal, deptno, dname
FROM emp NATURAL JOIN dept;
指定特定同名欄位進行等值連接。
SELECT empno, ename, sal, deptno, dname
FROM emp JOIN dept USING (deptno);
支援任意連接條件,含非同名欄位。
SELECT empno, ename, sal, emp.deptno, dname
FROM emp JOIN dept ON (emp.deptno = dept.deptno);
-- 左外連接
SELECT employee_id, last_name, salary, department_id, department_name
FROM employees LEFT JOIN departments USING (department_id);
-- 右外連接
SELECT ... FROM employees RIGHT JOIN departments ...;
-- 全外連接
SELECT ... FROM employees FULL OUTER JOIN departments ...;
ORDER BY。-- 查詢薪資高於 7654 號員工的所有人員
SELECT * FROM emp
WHERE sal > (SELECT sal FROM emp WHERE empno = 7654);
IN, ANY, ALL。-- 非法:多行結果用單列運算子
SELECT * FROM emp WHERE sal > (SELECT AVG(sal) FROM emp GROUP BY deptno);
-- 合法:使用 IN
SELECT * FROM emp WHERE sal IN (SELECT MAX(sal) FROM emp GROUP BY deptno);
SELECT * FROM (
SELECT * FROM emp ORDER BY sal DESC
) WHERE ROWNUM <= 5;
WHERE ROWNUM <= 5 ORDER BY sal DESC 會先取前 5 筆再排序,非預期結果。ROWNUM >= 5 永無結果(首列 ROWNUM=1 不符合被過濾,下一列仍為 1)。SELECT * FROM (
SELECT ROWNUM rn, a.* FROM (
SELECT * FROM emp ORDER BY sal DESC
) a
) WHERE rn BETWEEN 5 AND 10;
關鍵步驟:
ROWNUM 別名 (rn),使其成為實質欄位可比較。注意:外層若直接用 ROWNUM 而非別名,仍指向外層查詢新產生的偽欄,無法達到分頁效果。